Archive for the 'NSURLRequest' Category

2017/07/09 指定URLにリンクされているPDFをすべて指定のフォルダにダウンロードする

指定URLのHTMLにリンクされているPDFをすべて指定のフォルダにダウンロードするAppleScriptです。

従来、この手の処理はSafariに対してdo javascript命令を実行していましたが、呼び出しにそこそこ時間がかかります。

そこで、SafariまかせにせずにAppleScript側でオープンソースのフレームワーク「HTMLReader」を呼び出してHTMLを解析したところ、圧倒的に高速になりました。

同じページ内のリンク箇所の抽出処理だと、

  Safari+do javascript:89 seconds
  HTMLReader.framework:0.064 seconds (First Run Time:0.831 seconds)

と、Safariに対してdo javascriptコマンドを実行しないAppleScriptのほうが100〜1,400倍高速に処理できています。本Script全体の処理時間については、PDFのダウンロード処理をともなうためネットワークの速さに依存しますが、1分かからない程度で終わることでしょう。Safari+do javascriptだとリンク先の抽出がまだ終わっていないぐらいの時間です。

実行にあたっては、HTMLReaderのプロジェクトをダウンロードしてXcode上でビルドし、出来上がったフレームワークのバイナリを~/Library/Frameworksにインストールしておく必要があります。

ただ、PDFのURLが厳密にわかっている連番のファイルならshellのcurlコマンドを呼び出してダウンロードさせれば1行で終わってしまう内容ではあります。

AppleScript名:指定URLにリンクされているPDFをすべて指定のフォルダにダウンロードする
– Created 2017-07-09 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “HTMLReader” –https://github.com/nolanw/HTMLReader
–http://piyocast.com/as/archives/4720

set aTargFol to POSIX path of (choose folder with prompt “PDFダウンロード先のフォルダを選択”)
set aTargPath to current application’s NSString’s stringWithString:aTargFol

set aStr to “http://yakumo-tajimi.com/dl.html” –Safariの最前面のウィンドウからとってきてもよい
set aList to getWebLinkURLs(aStr, “pdf”) of me

repeat with i in aList
  set j to contents of i
  
set jURL to (current application’s |NSURL|’s URLWithString:j)
  
set {exRes, headerRes, aData} to checkURLResourceExistence(jURL, 10) of me
  
  
if exRes = true then
    set cURL to (current application’s |NSURL|’s URLWithString:j)
    
set cFileName to (cURL’s |lastPathComponent|()) as string
    
set savePath to (aTargPath’s stringByAppendingPathComponent:cFileName)
    
set wRes to (aData’s writeToFile:savePath atomically:true)
  end if
end repeat

–指定のURLのページのHTMLソースからリンクを抽出して、指定拡張子に合うものだけをフルパスのURL化して返す
on getWebLinkURLs(anURLstr, linkFileExt)
  –URLの妥当性チェック(存在チェック)
  
set aURL to (current application’s |NSURL|’s URLWithString:anURLstr)
  
set {exRes, headerRes, aData} to checkURLResourceExistence(aURL, 3) of me
  
if exRes = false then error “Illegal URL Error” –エラー発生時に処理打ち切り
  
  
–HTMLのソースを取得する
  
set conType to headerRes’s valueForKeyPath:“Content-Type”
  
set aHTML to current application’s HTMLDocument’s documentWithData:aData contentTypeHeader:conType
  
  
–リンク箇所を抽出
  
set aTextArray to ((aHTML’s nodesMatchingSelector:“a”)’s textContent) as list –リンク文字
  
set aLinkArray to ((aHTML’s nodesMatchingSelector:“a”)’s attributes’s valueForKeyPath:“href”) as list –URL
  
  
  
–取得したリンクを拡張子で絞り込みつつ、それぞれフルパスのURLを組み立てる
  
set urlList to {}
  
set aaURL to aURL’s URLByDeletingLastPathComponent()
  
  
repeat with i in aLinkArray
    set bURL to (current application’s |NSURL|’s URLWithString:i)
    
set aRes to (bURL’s |scheme|()) as string
    
set aExt to (bURL’s |pathExtension|()) as string
    
    
if aRes = “missing value” and aExt = linkFileExt then
      –想定URL(指定サイト内)のファイルへのリンクの処理
      
set aaaURL to (aaURL’s URLByAppendingPathComponent:i)
      
set aaaURLstr to (aaaURL’s absoluteString()) as string
      
set the end of urlList to aaaURLstr
    else if aRes is not “missing value” and aExt = linkFileExt then
      –指定外のURL(想定サイト外のファイルへのリンクなど)の処理
      
set the end of urlList to (aaURL’s absoluteString()) as string
    end if
  end repeat
  
  
–重複部分を除去してユニークなリストにして返す
  
return uniquify1DList(urlList, true) of me
end getWebLinkURLs

– 指定URLにファイル(画像など)が存在するかチェック
–> {存在確認結果(boolean), レスポンスヘッダー(NSDictionary), データ(NSData)}
on checkURLResourceExistence(aURL, timeOutSec as real)
  set aRequest to (current application’s NSURLRequest’s requestWithURL:aURL cachePolicy:(current application’s NSURLRequestUseProtocolCachePolicy) timeoutInterval:timeOutSec)
  
set aRes to (current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value))
  
set dRes to (first item of (aRes as list))
  
set bRes to (second item of (aRes as list))
  
if bRes is not equal to missing value then
    set hRes to (bRes’s allHeaderFields())
    
set aResCode to (bRes’s statusCode()) as integer
  else
    set hRes to {}
    
set aResCode to -1 –error
  end if
  
return {(aResCode = 200), hRes, dRes}
end checkURLResourceExistence

–1D/2D Listをユニーク化
on uniquify1DList(theList as list, aBool as boolean)
  set aArray to current application’s NSArray’s arrayWithArray:theList
  
set bArray to aArray’s valueForKeyPath:“@distinctUnionOfObjects.self”
  
return bArray as list
end uniquify1DList

★Click Here to Open This Script 

2016/11/21 HTMLReaderでWeb上のHTMLからリンクを取得する

オープンソースのフレームワーク「HTMLReader」を用いて、指定のURLのHTMLをダウンロードして指定要素を取り出すAppleScriptです。

実行にあたっては、HTMLReaderをダウンロードしてビルドし、~/Library/Frameworksにインストールしておく必要があります。

AppleScript名:HTMLReaderでWeb上のHTMLからリンクを取得する
– Created 2016-11-21 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “HTMLReader” –https://github.com/nolanw/HTMLReader
–http://piyocast.com/as/archives/4325

set aStr to “https://github.com/nolanw/HTMLReader”
set aURL to (current application’s |NSURL|’s URLWithString:aStr)
set {exRes, headerRes, aData} to checkURLResourceExistence(aURL, 3) of me
if exRes = false then return –エラー発生時に処理打ち切り

set conType to headerRes’s valueForKeyPath:“Content-Type”
set aHTML to current application’s HTMLDocument’s documentWithData:aData contentTypeHeader:conType

set aTextArray to ((aHTML’s nodesMatchingSelector:“a”)’s textContent) as list –リンク文字
set aLinkArray to ((aHTML’s nodesMatchingSelector:“a”)’s attributes’s valueForKeyPath:“href”) as list –URL
–> {”#start-of-content”, “https://github.com/”, “/personal”, “/open-source”, “/business”, “/explore”, “/join?source=header-repo”, “/login?return_to=%2Fnolanw%2FHTMLReader”, “/pricing”, “/blog”, …….}

– 指定URLにファイル(画像など)が存在するかチェック
–> {存在確認結果(boolean), レスポンスヘッダー(NSDictionary), データ(NSData)}
on checkURLResourceExistence(aURL, timeOutSec as real)
  set aRequest to (current application’s NSURLRequest’s requestWithURL:aURL cachePolicy:(current application’s NSURLRequestUseProtocolCachePolicy) timeoutInterval:timeOutSec)
  
set aRes to (current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value))
  
set dRes to (first item of (aRes as list))
  
set bRes to (second item of (aRes as list))
  
if bRes is not equal to missing value then
    set hRes to (bRes’s allHeaderFields())
    
set aResCode to (bRes’s statusCode()) as integer
  else
    set hRes to {}
    
set aResCode to -1 –error
  end if
  
return {(aResCode = 200), hRes, dRes}
end checkURLResourceExistence

★Click Here to Open This Script 

AppleScript名:HTMLReaderでWeb上のHTMLから画像リンクを取得する
– Created 2016-11-21 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “HTMLReader” –https://github.com/nolanw/HTMLReader
–http://piyocast.com/as/archives/4325

set aStr to “https://github.com/nolanw/HTMLReader”
set aURL to (current application’s |NSURL|’s URLWithString:aStr)
set {exRes, headerRes, aData} to checkURLResourceExistence(aURL, 3) of me
if exRes = false then return –エラー発生時に処理打ち切り

set conType to headerRes’s valueForKeyPath:“Content-Type”
set aHTML to current application’s HTMLDocument’s documentWithData:aData contentTypeHeader:conType

set aLinkArray to ((aHTML’s nodesMatchingSelector:“img”)’s attributes’s valueForKeyPath:“src”) as list –画像リンクURLを取得
–> {”https://avatars2.githubusercontent.com/u/177228?v=3&s=40″, “https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif”, “https://assets-cdn.github.com/images/spinners/octocat-spinner-32.gif”, ….

– 指定URLにファイル(画像など)が存在するかチェック
–> {存在確認結果(boolean), レスポンスヘッダー(NSDictionary), データ(NSData)}
on checkURLResourceExistence(aURL, timeOutSec as real)
  set aRequest to (current application’s NSURLRequest’s requestWithURL:aURL cachePolicy:(current application’s NSURLRequestUseProtocolCachePolicy) timeoutInterval:timeOutSec)
  
set aRes to (current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value))
  
set dRes to (first item of (aRes as list))
  
set bRes to (second item of (aRes as list))
  
if bRes is not equal to missing value then
    set hRes to (bRes’s allHeaderFields())
    
set aResCode to (bRes’s statusCode()) as integer
  else
    set hRes to {}
    
set aResCode to -1 –error
  end if
  
return {(aResCode = 200), hRes, dRes}
end checkURLResourceExistence

★Click Here to Open This Script 

2016/10/29 同義語辞書【新語対応】

Apitoreの「同義語辞書【新語対応】」APIを呼び出して、指定の日本語の単語の同義語(っぽいもの)を返すAppleScriptです。

実行前にapitoreにユーザー登録を行い(無料)、Web上でアクセストークンを取得。そのトークンをretAccessToken()内で返すように書いておく必要があります(掲載のリストのまま実行すると、エラーになります。かならずアクセストークンを取得してください)。

一般的なシソーラス的な動作を行うわけではなく、固有名詞に特化しているとのこと。そこで、「ガンダム」を渡してみたところ、

{input:”ガンダム”, endTime:”1477742279389″, processTime:”1019″, log:”Success.”, distances:{{word:”ζガンダム”, distance:0.819100677967}, {word:”rx-78″, distance:0.798426866531}, {word:”ζζガンダム”, distance:0.794555306435}, {word:”ザク”, distance:0.783695220947}, {word:”zガンダム”, distance:0.776543617249}, {word:”フルアーマー”, distance:0.757733106613}, {word:”gアーマー”, distance:0.75621265173}, {word:”νガンダム”, distance:0.754522383213}, {word:”ガンキャノン”, distance:0.752012193203}, {word:”モビルスーツ”, distance:0.744036734104}}, startTime:”1477742278370″, num:”10″}

やや、ゴミ(ζガンダム、ζζガンダム)が入っているようです。また、「グフ・カスタム」を入力してみると、

{input:”グフ・カスタム”, endTime:”1477742501687″, processTime:”934″, log:”Success.”, distances:{{word:”sideral”, distance:0.922877013683}, {word:”北海道道104号網走端野線”, distance:0.922159075737}, {word:”北海道道966号十勝岳温泉美瑛線”, distance:0.921318411827}, {word:”kuttner”, distance:0.916471898556}, {word:”北海道道102号網走川湯線”, distance:0.915675938129}, {word:”北海道道42号八雲北檜山線”, distance:0.915441274643}, {word:”三浦隆”, distance:0.914838135242}, {word:”桧山泰浩”, distance:0.914380848408}, {word:”北海道道120号美深中頓別線”, distance:0.914329528809}, {word:”knipex”, distance:0.913379848003}}, startTime:”1477742500753″, num:”10″}

と、関係ない言葉が返ってくるようです。Wikipediaに項目が単独で存在しているような単語と、その関連語では本サービス上での扱いが異なるように感じられます。

AppleScript名:同義語辞書【新語対応】
– Created 2016-10-27 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.5″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4294

set reqURLStr to “https://api.apitore.com/api/9/word2vec-neologd-jawiki/distance”
set accessToken to retAccessToken() —Access Token
set aRec to {access_token:accessToken, |word|:“ガンダム”, num:“10″}
set aURL to retURLwithParams(reqURLStr, aRec) of me

set aRes to callRestGETAPIAndParseResults(aURL) of me

set aRESTres to (json of aRes) as record
return aRESTres
–>  {input:”ガンダム”, endTime:”1477742279389″, processTime:”1019″, log:”Success.”, distances:{{word:”ζガンダム”, distance:0.819100677967}, {word:”rx-78″, distance:0.798426866531}, {word:”ζζガンダム”, distance:0.794555306435}, {word:”ザク”, distance:0.783695220947}, {word:”zガンダム”, distance:0.776543617249}, {word:”フルアーマー”, distance:0.757733106613}, {word:”gアーマー”, distance:0.75621265173}, {word:”νガンダム”, distance:0.754522383213}, {word:”ガンキャノン”, distance:0.752012193203}, {word:”モビルスーツ”, distance:0.744036734104}}, startTime:”1477742278370″, num:”10″}

–>  {input:”グフ・カスタム”, endTime:”1477742501687″, processTime:”934″, log:”Success.”, distances:{{word:”sideral”, distance:0.922877013683}, {word:”北海道道104号網走端野線”, distance:0.922159075737}, {word:”北海道道966号十勝岳温泉美瑛線”, distance:0.921318411827}, {word:”kuttner”, distance:0.916471898556}, {word:”北海道道102号網走川湯線”, distance:0.915675938129}, {word:”北海道道42号八雲北檜山線”, distance:0.915441274643}, {word:”三浦隆”, distance:0.914838135242}, {word:”桧山泰浩”, distance:0.914380848408}, {word:”北海道道120号美深中頓別線”, distance:0.914329528809}, {word:”knipex”, distance:0.913379848003}}, startTime:”1477742500753″, num:”10″}

set aRESCode to responseCode of aRes
–>  200

set aRESHeader to responseHeader of aRes

–GET methodのREST APIを呼ぶ
on callRestGETAPIAndParseResults(aURL)
  
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
  
aRequest’s setHTTPMethod:“GET”
  
aRequest’s setCachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData)
  
aRequest’s setHTTPShouldHandleCookies:false
  
aRequest’s setTimeoutInterval:60
  
aRequest’s setValue:“application/json” forHTTPHeaderField:“Accept”
  
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
set resList to aRes as list
  
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
–Get Response Code & Header
  
set dRes to contents of second item of resList
  
if dRes is not equal to missing value then
    set resCode to (dRes’s statusCode()) as number
    
set resHeaders to (dRes’s allHeaderFields()) as record
  else
    set resCode to 0
    
set resHeaders to {}
  end if
  
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
  
end callRestGETAPIAndParseResults

on retURLwithParams(aBaseURL, aRec)
  set aDic to current application’s NSMutableDictionary’s dictionaryWithDictionary:aRec
  
  
set aKeyList to (aDic’s allKeys()) as list
  
set aValList to (aDic’s allValues()) as list
  
set aLen to length of aKeyList
  
set bLen to length of aValList
  
if aLen is not equal to bLen then return false
  
  
set qList to {}
  
repeat with i from 1 to aLen
    set aName to contents of item i of aKeyList
    
set aVal to contents of item i of aValList
    
set the end of qList to (current application’s NSURLQueryItem’s queryItemWithName:aName value:aVal)
  end repeat
  
  
set aComp to current application’s NSURLComponents’s alloc()’s initWithString:aBaseURL
  
aComp’s setQueryItems:qList
  
set aURL to (aComp’s |URL|()’s absoluteString()) as text
  
  
return aURL
end retURLwithParams

on retAccessToken()
  return “XXxXXXxx-XXxX-XXXx-XXxX-XXxxXxXXXxXX” –API Tore Access Token
end retAccessToken

on urlencodeStr(aStr)
  set aString to current application’s NSString’s stringWithString:aStr
  
set aString to (aString’s stringByAddingPercentEncodingWithAllowedCharacters:(current application’s NSCharacterSet’s URLQueryAllowedCharacterSet())) as text
  
return aString
end urlencodeStr

★Click Here to Open This Script 

2016/10/18 URLにリソースが存在するかチェック v3

指定したURLにリソース(ファイル)が存在するかを確認するAppleScriptの改良版です。

Webサーバーなどのリモート環境を指しているURLをファイル名までフルに記述して、画像ファイルなどの存在確認を行います。「存在確認だけ」を行うことができないので、確認すると実際にデータも取得します。

  結果:{存在確認(true/false), レスポンスヘッダー(NSDictionary), データ本体(NSData)}

v3では、Webサーバーに問い合わせを行ってエラーになったときの対応を追加しています。

AppleScript名:URLにリソースが存在するかチェック v3
– Created 2016-10-18 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4279

set aStr to “http://piyocast.com/as/wp-content/uploads/2016/10/xfinder2.jpg.pagespeed.ic.jFDNAr4CuI.jpg”

set aURL to (current application’s |NSURL|’s URLWithString:aStr)
set {exRes, headerRes, aData} to checkURLResourceExistence(aURL, 3) of me

exRes
–> true / false

headerRes
–> (NSDictionary) {Connection:”Keep-Alive”, Content-Type:”image/jpeg”, Server:”Apache”, Last-Modified:”Mon, 10 Oct 2016 03:43:53 GMT”, Expires:”Tue, 10 Oct 2017 03:43:53 GMT”, Cache-Control:”max-age=31536000″, Accept-Ranges:”bytes”, Date:”Mon, 10 Oct 2016 05:24:38 GMT”, Keep-Alive:”timeout=1, max=100″, Content-Length:”4383″, Etag:”W/”0″”}

aData
–> (NSData)

set conType to (headerRes’s valueForKey:“Content-Type”) as string
–>  ”image/jpeg”

set modDate to (headerRes’s valueForKey:“Last-Modified”) as string
–>  ”Mon, 10 Oct 2016 03:43:53 GMT”

– 指定URLにファイル(画像など)が存在するかチェック
–> {存在確認結果(boolean), レスポンスヘッダー(NSDictionary), データ(NSData)}
on checkURLResourceExistence(aURL, timeOutSec as real)
  set aRequest to (current application’s NSURLRequest’s requestWithURL:aURL cachePolicy:(current application’s NSURLRequestUseProtocolCachePolicy) timeoutInterval:timeOutSec)
  
set aRes to (current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value))
  
set dRes to (first item of (aRes as list))
  
set bRes to (second item of (aRes as list))
  
if bRes is not equal to missing value then
    set hRes to (bRes’s allHeaderFields())
    
set aResCode to (bRes’s statusCode()) as integer
  else
    set hRes to {}
    
set aResCode to -1 –error
  end if
  
return {(aResCode = 200), hRes, dRes}
end checkURLResourceExistence

★Click Here to Open This Script 

2016/10/10 URLにリソースが存在するかチェック v2

指定したURLにリソース(ファイル)が存在するかを確認するAppleScriptです。

Webサーバーなどのリモート環境を指しているURLをファイル名までフルに記述して、画像ファイルなどの存在確認を行います。

ただし、「存在確認だけ」を行うことができないようで、確認すると実際にデータも取得できてしまいます。

本来なら、このような処理は並列で同時に行いたいところ。強制的に並列化するツールも作って実験していますが、同時に大量のURLの存在確認を行うような処理はとてもありえそうです。

ただ、shell commandで行なっても割と手軽にできそうで、Cocoaのサービスを呼び出すのか、実際に処理速度を計測して選択したいところです。

AppleScript名:URLにリソースが存在するかチェック v2
– Created 2016-10-10 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4254

set aStr to “http://piyocast.com/as/wp-content/uploads/2016/10/xfinder2.jpg.pagespeed.ic.jFDNAr4CuI.jpg”

set aURL to (current application’s |NSURL|’s URLWithString:aStr)
set {exRes, headerRes, aData} to checkURLResourceExistence(aURL, 3) of me

exRes
–> true / false

headerRes
–> (NSDictionary) {Connection:”Keep-Alive”, Content-Type:”image/jpeg”, Server:”Apache”, Last-Modified:”Mon, 10 Oct 2016 03:43:53 GMT”, Expires:”Tue, 10 Oct 2017 03:43:53 GMT”, Cache-Control:”max-age=31536000″, Accept-Ranges:”bytes”, Date:”Mon, 10 Oct 2016 05:24:38 GMT”, Keep-Alive:”timeout=1, max=100″, Content-Length:”4383″, Etag:”W/”0″”}

aData
–> (NSData)

set conType to (headerRes’s valueForKey:“Content-Type”) as string
–>  ”image/jpeg”

set modDate to (headerRes’s valueForKey:“Last-Modified”) as string
–>  ”Mon, 10 Oct 2016 03:43:53 GMT”

– 指定URLにファイル(画像など)が存在するかチェック
–> {存在確認結果(boolean), レスポンスヘッダー(NSDictionary), データ(NSData)}
on checkURLResourceExistence(aURL, timeOutSec as real)
  set aRequest to (current application’s NSURLRequest’s requestWithURL:aURL cachePolicy:(current application’s NSURLRequestUseProtocolCachePolicy) timeoutInterval:timeOutSec)
  
set aRes to (current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value))
  
set dRes to (first item of (aRes as list))
  
set bRes to (second item of (aRes as list))
  
set hRes to (bRes’s allHeaderFields())
  
set aResCode to (bRes’s statusCode()) as integer
  
return {(aResCode = 200), hRes, dRes}
end checkURLResourceExistence

★Click Here to Open This Script 

2016/03/06 REST APIに対してGET、POST、PUT、DELETEのmethodを呼び出す

AppleScriptでWeb上のREST APIを呼び出すじっけんです。Web上にあるREST APIの実験用サービスJSONPlaceholderをAppleScriptから呼び出して各種メソッド呼び出しの実証を行ってみました。

できてしまえばたいしたことはありませんが、地道に調査しておかないと今日明日でいきなりやれと言われても困ってしまいます。

実際に、NTTdocomoの形態素解析のREST APIをmethod=POSTでAppleScriptから呼び出してみたところ、

–> (NSDictionary) {request_id:”record001″, word_list:{{{”私”}, {”の”}, {”名前”}, {”は”}, {” ”}, {”長野”}, {”谷”}, {”です”}, {”。”}}}, info_filter:”form”}

となりました(words ofの実行結果と変わり映えしない、、、、)。固有名詞としてあらかじめ人名を登録しておきたいケースがほとんどなので、ちょっとこれだと使えない感じではあります。ただ、実際に稼働しているAPIを呼べることは実証できました。

AppleScript名:GET method REST API
– Created 2016-03-03 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

set reqURLStr to “http://jsonplaceholder.typicode.com/posts”

set aRes to callRestGETAPIAndParseResults(reqURLStr) of me

set aRESTres to json of aRes
–>  (NSArray) {{body:”quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto”, id:1, title:”sunt aut facere repellat provident occaecati excepturi optio reprehenderit”, userId:1},…

set aRESCode to responseCode of aRes
–>  200

set aRESHeader to responseHeader of aRes
–>  {Content-Type:”application/json; charset=utf-8″, Pragma:”no-cache”, X-Powered-By:”Express”, Via:”1.1 vegur”, Server:”Cowboy”, Expires:”-1″, Cache-Control:”no-cache”, Date:”Sun, 06 Mar 2016 07:27:26 GMT”, Access-Control-Allow-Credentials:”true”, Content-Length:”27520″, Connection:”keep-alive”, X-Content-Type-Options:”nosniff”, Etag:”W/\”6b80-uPwhAkDat3Fl5TugzmyYpQ\”", Vary:”Origin”}

–GET methodのREST APIを呼ぶ
on callRestGETAPIAndParseResults(aURL)
  load framework
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
aRequest’s setHTTPMethod:“GET”
  
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
set resList to aRes as list
  
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
–Get Response Code
  
set dRes to contents of second item of resList
  
set resCode to ASify from (dRes’s statusCode())
  
  
–Get Response Header
  
set resHeaders to ASify from (dRes’s allHeaderFields())
  
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
  
end callRestGETAPIAndParseResults

★Click Here to Open This Script 

AppleScript名:POST method REST API
– Created 2016-03-06 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

set reqURLStr to “http://jsonplaceholder.typicode.com/posts”
set aPostData to {title:“foo”, body:“bar”, userId:1}

set aRes to callRestPOSTAPIAndParseResults(reqURLStr, aPostData) of me

set aRESTres to json of aRes
–>  (NSDictionary) {body:”bar”, id:101, title:”foo”, userId:1}

set aRESCode to responseCode of aRes
–>  200

set aRESHeader to responseHeader of aRes
–>  {Content-Type:”application/json; charset=utf-8″, Pragma:”no-cache”, X-Powered-By:”Express”, Via:”1.1 vegur”, Server:”Cowboy”, Expires:”-1″, Cache-Control:”no-cache”, Date:”Sun, 06 Mar 2016 07:47:56 GMT”, Access-Control-Allow-Credentials:”true”, Content-Length:”65″, Connection:”keep-alive”, X-Content-Type-Options:”nosniff”, Etag:”W/\”41-DL1IzEbjanDFwm6hF2BfJw\”", Vary:”Origin, X-HTTP-Method-Override”}

–POST methodのREST APIを呼ぶ
on callRestPOSTAPIAndParseResults(aURL, aPostData)
  load framework
  
set dataJson to current application’s NSJSONSerialization’s dataWithJSONObject:aPostData options:0 |error|:(missing value)
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
  
aRequest’s setHTTPMethod:“POST”
  
aRequest’s setHTTPBody:dataJson
  
aRequest’s setValue:“application/json” forHTTPHeaderField:“Accept”
  
aRequest’s setValue:“application/json” forHTTPHeaderField:“Content-Type”
  
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
set resList to aRes as list
  
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
–Get Response Code
  
set dRes to contents of second item of resList
  
set resCode to ASify from (dRes’s statusCode())
  
  
–Get Response Header
  
set resHeaders to ASify from (dRes’s allHeaderFields())
  
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
  
end callRestPOSTAPIAndParseResults

★Click Here to Open This Script 

AppleScript名:PUT method REST API
– Created 2016-03-06 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

set reqURLStr to “http://jsonplaceholder.typicode.com/posts/1″
set aPostData to {title:“ぴよまるソフトウェア”, body:“PUTのじっけん”, userId:1}
–set aPostData to {title:”foo”, body:”bar”, userId:1}

set aRes to callRestPUTAPIAndParseResults(reqURLStr, aPostData) of me

set aRESTres to json of aRes
–>  (NSDictionary) {body:”PUTのじっけん”, id:1, title:”ぴよまるソフトウェア”, userId:1}
return aRESTres
set aRESCode to responseCode of aRes
–>  200

set aRESHeader to responseHeader of aRes
–>  {Content-Type:”application/json; charset=utf-8″, Pragma:”no-cache”, X-Powered-By:”Express”, Via:”1.1 vegur”, Server:”Cowboy”, Expires:”-1″, Cache-Control:”no-cache”, Date:”Sun, 06 Mar 2016 07:47:56 GMT”, Access-Control-Allow-Credentials:”true”, Content-Length:”65″, Connection:”keep-alive”, X-Content-Type-Options:”nosniff”, Etag:”W/\”41-DL1IzEbjanDFwm6hF2BfJw\”", Vary:”Origin, X-HTTP-Method-Override”}

–PUT methodのREST APIを呼ぶ
on callRestPUTAPIAndParseResults(aURL, aPostData)
  load framework
  
set dataJson to current application’s NSJSONSerialization’s dataWithJSONObject:aPostData options:0 |error|:(missing value)
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
  
aRequest’s setHTTPMethod:“PUT”
  
aRequest’s setHTTPBody:dataJson
  
aRequest’s setValue:“application/json” forHTTPHeaderField:“Accept”
  
aRequest’s setValue:“application/json” forHTTPHeaderField:“Content-Type”
  
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
set resList to aRes as list
  
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
–Get Response Code
  
set dRes to contents of second item of resList
  
set resCode to ASify from (dRes’s statusCode())
  
  
–Get Response Header
  
set resHeaders to ASify from (dRes’s allHeaderFields())
  
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
  
end callRestPUTAPIAndParseResults

★Click Here to Open This Script 

AppleScript名:DELETE method REST API
– Created 2016-03-06 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

set reqURLStr to “http://jsonplaceholder.typicode.com/posts/1″

set aRes to callRestDELETEAPIAndParseResults(reqURLStr) of me

set aRESTres to json of aRes
–>  (NSDictionary) {}

set aRESCode to responseCode of aRes
–>  200

set aRESHeader to responseHeader of aRes
–>  {Content-Type:”application/json; charset=utf-8″, Pragma:”no-cache”, X-Powered-By:”Express”, Via:”1.1 vegur”, Server:”Cowboy”, Expires:”-1″, Cache-Control:”no-cache”, Date:”Sun, 06 Mar 2016 07:53:51 GMT”, Access-Control-Allow-Credentials:”true”, Content-Length:”2″, Connection:”keep-alive”, X-Content-Type-Options:”nosniff”, Etag:”W/\”2-mZFLkyvTelC5g8XnyQrpOw\”", Vary:”Origin”}

–DELETE methodのREST APIを呼ぶ
on callRestDELETEAPIAndParseResults(aURL)
  load framework
  
set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
set respF to false
  
  
aRequest’s setHTTPMethod:“DELETE”
  
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
set resList to aRes as list
  
  
set bRes to contents of (first item of resList)
  
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
  
  
set jsonString to current application’s NSString’s stringWithString:resStr
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
–Get Response Code
  
set dRes to contents of second item of resList
  
set resCode to ASify from (dRes’s statusCode())
  
  
–Get Response Header
  
set resHeaders to ASify from (dRes’s allHeaderFields())
  
  
return {json:aJsonDict, responseCode:resCode, responseHeader:resHeaders}
  
end callRestDELETEAPIAndParseResults

★Click Here to Open This Script 

2016/03/03 REST APIを呼ぶじっけん

Web上のREST APIのサービスを呼び出すAppleScriptです。

なかなか呼び出すのに苦労させられていたWeb上のREST APIを呼び出すための実験的なAppleScriptのコードです。

いろいろなAPIを見て回っていると、音声認識APIなどは音声ファイルをアップロードしてやる必要があるケースもあるため、こんな簡単な呼び出し方だけでは済まないようですが、、、

rest1.png

とりあえず、REST APIのテスト用アプリケーション「Cocoa Rest Client」で呼べることを確認したAPIについて、AppleScriptの実行結果と付け合わせて納得できる内容が得られたので、満足しています。

rest2.png

ほかにも、githubのREST APIを呼んでみたところ、きちんと結果が取得できました。

AppleScript名:REST APIを呼ぶじっけん
– Created 2016-03-03 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set reqURLStr to "http://demos.xojo.com/EEWS/index.cgi/GetAllCustomers"
–set reqURLStr to "https://api.github.com/repos/mmattozzi/cocoa-rest-client/releases"

set aRequest to current application’s NSURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:reqURLStr)
set respF to false
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
set resList to aRes as list
log {length of resList}
–> {2}

set bRes to contents of (first item of resList)
set resStr to current application’s NSString’s alloc()’s initWithData:bRes encoding:(current application’s NSUTF8StringEncoding)
–>  (NSString) "{"GetAllCustomers":{"10174":{"FirstName":"Abdul","LastName":"Mcconnell","City":"Colorado Springs","State":"CO","Zip":"80935"},….

–Get Response Code
set cRes to contents of second item of resList
set resCode to cRes’s statusCode()
–>  404

–Get Response Header
set resHeaders to cRes’s allHeaderFields()
–>  (NSDictionary) {Content-Encoding:"gzip", Content-Type:"text/html; charset=UTF-8", Content-Length:"5376", Connection:"close", Server:"Apache/2.2.15 (CentOS)", Date:"Thu, 03 Mar 2016 13:44:22 GMT"}

★Click Here to Open This Script 

2016/02/09 指定URLのJSONをダウンロードしてRecordに変換 v2.1

指定URLのJSONデータを取得して、結果をrecordに変換するAppleScriptです。AppleScript Libraries「BridgePlus」を利用するように変更してみました。

AppleScript名:指定URLのJSONをダウンロードしてRecordに変換 v2.1
– Created 2016-02-06 by Takaaki Naganoya
– Modified 2016-02-08 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlus : script “BridgePlus”

–東京電力電力供給状況API JSON URL(指定された日時の電力使用状況を返す)
set a to downloadAndParseJSON(“http://tepco-usage-api.appspot.com/2016/2/6/19.json”) of me
–>  {forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:”2012-02-05 08:30:00″, usage:3720, forecast_peak_updated:”2012-02-05 08:30:00″, day:6, usage_updated:”2016-02-06 11:05:05″, capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:19, entryfor:”2016-02-06 10:00:00″}

–東京電力電力供給状況API JSON URL(指定された日の毎時の電力使用状況を、配列として返す)
set b to downloadAndParseJSON(“http://tepco-usage-api.appspot.com/2016/2/6.json”) of me
–>  {{forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:”2012-02-05 08:30:00″, usage:3081, forecast_peak_updated:”2012-02-05 08:30:00″, day:6, usage_updated:”2016-02-05 16:05:06″, capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:0, entryfor:”2016-02-05 15:00:00″}…….{forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:”2012-02-05 08:30:00″, usage:3645, forecast_peak_updated:”2012-02-05 08:30:00″, day:6, usage_updated:”2016-02-06 12:05:07″, capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:20, entryfor:”2016-02-06 11:00:00″}}

–東京電力電力供給状況API JSON URL(指定された月の毎日毎時の電力使用状況を、配列として返す)
set c to downloadAndParseJSON(“http://tepco-usage-api.appspot.com/2016/2.json”) of me
–>  {{forecast_peak_period:18, forecast_peak_usage:4260, capacity_updated:”2012-01-31 23:30:00″, usage:2901, forecast_peak_updated:”2012-01-31 23:30:00″, day:1, usage_updated:”2016-01-31 16:05:04″, capacity:4641, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:0, entryfor:”2016-01-31 15:00:00″}……{forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:”2012-02-05 08:30:00″, usage:3645, forecast_peak_updated:”2012-02-05 08:30:00″, day:6, usage_updated:”2016-02-06 12:05:07″, capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:20, entryfor:”2016-02-06 11:00:00″}}

on downloadAndParseJSON(aURL)
  set aRes to downloadDataFromWeb(aURL, 30) of me
  
if aRes = false then return false –download error
  
  
set jsonString to current application’s NSString’s stringWithString:aRes
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
set bRes to ASify from aJsonDict
  
return bRes
end downloadAndParseJSON

on downloadDataFromWeb(aURL, timeOutSec)
  set aURL to current application’s |NSURL|’s alloc()’s initWithString:aURL
  
set aReq to current application’s NSURLRequest’s alloc()’s initWithURL:aURL cachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:timeOutSec
  
set urlRes to (current application’s NSURLConnection’s sendSynchronousRequest:aReq returningResponse:(missing value) |error|:(missing value))
  
  
if urlRes = missing value then
    return false –Download Error
  else
    set aVal to (current application’s NSString’s alloc()’s initWithData:urlRes encoding:(current application’s NSUTF8StringEncoding))
    
return aVal
  end if
end downloadDataFromWeb

★Click Here to Open This Script 

2016/02/06 指定URLのJSONをダウンロードしてRecordに変換 v2

指定URLのJSONデータを取得して、結果をrecordに変換するAppleScriptです。結果をrecordとして返すAPIのほかrecordのlistで返すものもあるようなので、対応させてみました。

AppleScript名:指定URLのJSONをダウンロードしてRecordに変換 v2
– Created 2016-02-06 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

on run
  –東京電力電力供給状況API JSON URL(指定された日時の電力使用状況を返す)
  
set a to downloadAndParseJSON("http://tepco-usage-api.appspot.com/2016/2/6/19.json") of me
  
–>  {forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:"2012-02-05 08:30:00", usage:3720, forecast_peak_updated:"2012-02-05 08:30:00", day:6, usage_updated:"2016-02-06 11:05:05", capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:19, entryfor:"2016-02-06 10:00:00"}
  
  
–東京電力電力供給状況API JSON URL(指定された日の毎時の電力使用状況を、配列として返す)
  
set b to downloadAndParseJSON("http://tepco-usage-api.appspot.com/2016/2/6.json") of me
  
–>  {{forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:"2012-02-05 08:30:00", usage:3081, forecast_peak_updated:"2012-02-05 08:30:00", day:6, usage_updated:"2016-02-05 16:05:06", capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:0, entryfor:"2016-02-05 15:00:00"}…….{forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:"2012-02-05 08:30:00", usage:3645, forecast_peak_updated:"2012-02-05 08:30:00", day:6, usage_updated:"2016-02-06 12:05:07", capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:20, entryfor:"2016-02-06 11:00:00"}}
  
  
  
–東京電力電力供給状況API JSON URL(指定された月の毎日毎時の電力使用状況を、配列として返す)
  
set c to downloadAndParseJSON("http://tepco-usage-api.appspot.com/2016/2.json") of me
  
–>  {{forecast_peak_period:18, forecast_peak_usage:4260, capacity_updated:"2012-01-31 23:30:00", usage:2901, forecast_peak_updated:"2012-01-31 23:30:00", day:1, usage_updated:"2016-01-31 16:05:04", capacity:4641, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:0, entryfor:"2016-01-31 15:00:00"}……{forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:"2012-02-05 08:30:00", usage:3645, forecast_peak_updated:"2012-02-05 08:30:00", day:6, usage_updated:"2016-02-06 12:05:07", capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:20, entryfor:"2016-02-06 11:00:00"}}
  
end run

on downloadAndParseJSON(aURL)
  set aRes to downloadDataFromWeb(aURL, 30) of me
  
if aRes = false then return false –download error
  
  
set jsonString to current application’s NSString’s stringWithString:aRes
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
—-recordとして評価して返す
  
try
    set aRec to aJsonDict as record
  end try
  
—-recordのlistとして評価して返す
  
try
    set aRec to aJsonDict as list
  on error
    return false
  end try
  
—–
  
return aRec
  
end downloadAndParseJSON

on downloadDataFromWeb(aURL, timeOutSec)
  set aURL to current application’s |NSURL|’s alloc()’s initWithString:aURL
  
set aReq to current application’s NSURLRequest’s alloc()’s initWithURL:aURL cachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:timeOutSec
  
set urlRes to (current application’s NSURLConnection’s sendSynchronousRequest:aReq returningResponse:(missing value) |error|:(missing value))
  
  
if urlRes = missing value then
    return false –Download Error
  else
    set aVal to (current application’s NSString’s alloc()’s initWithData:urlRes encoding:(current application’s NSUTF8StringEncoding))
    
return aVal
  end if
end downloadDataFromWeb

★Click Here to Open This Script 

2016/02/06 指定URLのJSONをダウンロードしてRecordに変換

指定URLのJSONデータを取得して、結果をrecordに変換するAppleScriptです。

Web上でいろいろサンプルを見繕っていたら、シンプルな例がなかなか存在しないため(わざと複雑に書いてあるのはなぜなんだろう?)、自分で簡単な例を書いてみました。

呼び出しているJSONのサービスは、@ssciさんが提供されている東京電力の最新の電力使用状況を返すものです。返ってくるデータの詳細については、「APIの使い方」をご参照ください

AppleScript名:指定URLのJSONをダウンロードしてRecordに変換
– Created 2015-12-16 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

on run
  –東京電力電力供給状況API JSON URL(最新の電力使用状況を返す)
  
set a to downloadAndParseJSON(“http://tepco-usage-api.appspot.com/latest.json”) of me
  
return a
  
–>  {forecast_peak_period:18, forecast_peak_usage:3670, capacity_updated:”2012-02-05 08:30:00″, usage:3720, forecast_peak_updated:”2012-02-05 08:30:00″, day:6, usage_updated:”2016-02-06 11:05:05″, capacity:4484, saving:false, year:2016, month:2, capacity_peak_period:18, forecast:0, hour:19, entryfor:”2016-02-06 10:00:00″}
end run

on downloadAndParseJSON(aURL)
  set aRes to downloadDataFromWeb(aURL, 30) of me
  
if aRes = false then return false –download error
  
  
set jsonString to current application’s NSString’s stringWithString:aRes
  
set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding)
  
set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
  
try
    set aRec to aJsonDict as record
  on error
    set aRec to false
  end try
  
  
return aRec
end downloadAndParseJSON

on downloadDataFromWeb(aURL, timeOutSec)
  set aURL to current application’s |NSURL|’s alloc()’s initWithString:aURL
  
set aReq to current application’s NSURLRequest’s alloc()’s initWithURL:aURL cachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:timeOutSec
  
set urlRes to (current application’s NSURLConnection’s sendSynchronousRequest:aReq returningResponse:(missing value) |error|:(missing value))
  
  
if urlRes = missing value then
    return false –Download Error
  else
    set aVal to (current application’s NSString’s alloc()’s initWithData:urlRes encoding:(current application’s NSUTF8StringEncoding))
    
return aVal
  end if
end downloadDataFromWeb

★Click Here to Open This Script 

2015/12/16 ASOCでインターネット接続確認

Cocoaの機能を用いたインターネット接続確認を行うAppleScriptです。

やり方はAppleScriptでもObjective-Cでも変わらないというか、AppleScriptでもはるかかなた昔から行われているやり方で使う道具が違うだけとか、そういう感じです。

AppleScript名:ASOCでインターネット接続確認
– Created 2015-12-16 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aRes to hasInternetConnection() of me
–>  true

on hasInternetConnection()
  set aURL to current application’s |NSURL|’s alloc()’s initWithString:“http://www.google.com”
  
set aReq to current application’s NSURLRequest’s alloc()’s initWithURL:aURL cachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:5.0
  
set urlRes to (current application’s NSURLConnection’s sendSynchronousRequest:aReq returningResponse:(missing value) |error|:(missing value))
  
if urlRes = missing value then
    return false
  else
    return true
  end if
end hasInternetConnection

★Click Here to Open This Script 

2015/09/09 指定URLのファイルをダウンロード

Cocoaの機能を用いて、指定URLのファイルをダウンロードするAppleScriptです。

書いている途中でどうしてもNSURLErrorDomain Error 3001が出てダウンロードできなかったのですが、それはダウンロード先をファイル名まで指定していなかったからでした(Appleのサンプルどおりに書いたのに!)。

最初の掲載時にはcachePolicyにNSURLRequestUseProtocolCachePolicyを指定していたのですが、ネット非接続時も正常終了したり、キャッシュが効いて最新版が取得できないなどの問題を見かけたため、NSURLRequestReloadIgnoringLocalCacheDataに変更しました。

AppleScript名:ASOCで指定URLのファイルをダウンロード
– Created 2015-09-09 Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

–https://developer.apple.com/library/mac/documentation/Cocoa/
– Conceptual/URLLoadingSystem/Tasks/UsingNSURLDownload.html

property dlF : false
property dlTimeOutSec : 60.0

set my dlF to false

–DL先はファイル名まで指定しないとエラー(Error 3001)になる
set theDLdir to (current application’s NSHomeDirectory())’s stringByAppendingPathComponent:“Desktop/index.html”
–>  (NSString) “/Users/me/Desktop”

downloadFrom(“http://www.apple.com/jp/index.html”, theDLdir) of me

set waitLoop to 1000 * dlTimeOutSec –60 seconds
set hitF to false
repeat waitLoop times
  if my dlF is not equal to false then
    set hitF to true
    
exit repeat
  end if
  
current application’s NSThread’s sleepForTimeInterval:(“0.001″ as real) –delay 0.001
end repeat
if hitF = false then return
return dlF
–>  true

on downloadFrom(aURLstr, dlDir)
  
  
set aURL to current application’s |NSURL|’s URLWithString:aURLstr
  
–>  (NSURL) http://www.apple.com
  
  
set theReq to current application’s NSURLRequest’s requestWithURL:aURL cachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:dlTimeOutSec
  
–>  (NSURLRequest) { URL: http://www.apple.com }
  
  
set theDownload to current application’s NSURLDownload’s alloc()’s initWithRequest:theReq delegate:me
  
–>  (NSURLDownload) { request: { URL: http://www.apple.com } }
  
  
theDownload’s setDestination:dlDir allowOverwrite:true
  
end downloadFrom

–Download Error Event Handler
on download:aDownload didFailWithError:anError
  set anErrorStr to anError’s localizedDescription()
  
set errorReason to (anError’s userInfo())’s objectForKey:(current application’s NSURLErrorFailingURLStringErrorKey)
  
set my dlF to {anErrorStr, errorReason}
end download:didFailWithError:

–Download Finished Event Handler
on downloadDidFinish:aDownload
  set my dlF to true
end downloadDidFinish:

★Click Here to Open This Script