Archive for 12月, 2016

2016/12/28 [特集] 2016年を振り返る

2016年の本Blogを振り返って、印象的なプログラムをピックアップしてみます。

今年の方向性は1月にすでに決定づけられました。RESTful APIを縦横無尽に呼び出せるようになり、クラウド側のパワーを時差なしで利用できるようになりました。ローカルアプリケーションとクラウドの組み合わせ(マッシュアップ)でさらに多彩な処理ができるようになった1年です。

また、AppleScript本「AppleScript最新リファレンス」および「最新事情がわかるAppleScript 10大最新技術」を電子出版で発行。最新の情報をこれだけ濃密にまとめた本は(日本国内では)ほかにありません。

2016/1/12「Cocoa勉強会関西にて発表を」

今年の本Blogおよび個人的な方向性を決定した出来事でした。本当に参加してよかったです。Cocoa勉強会関西では、Web系のエンジニアとの交流が盛ん(モバイル系で)であるため、クラウドのサービス呼び出しに関する発表が多く、とても刺激になりました。

実際にやってみたら大変簡単だったので、さまざまなクラウドAPI呼び出しを攻めてみることに。

2016/1/26「Cocoa勉強会関西に行ってきました!」

Cocoa勉強会関西のみなさまには、たいへんお世話になりました。また、参加してみたいですね。

注:その後、Cocoa勉強会 池袋とCocoa勉強会 松戸にも年間を通じて参加させていただいております。

2016/2/22「YouTubeへのムービーアップロードのじっけん」

今年もいろいろなGithub上のオープンソースのプロジェクトをCocoa FrameworkにビルドしてはAppleScriptから呼び出すという無茶なことをやっていました。YouTubeへのアップロードがAppleScriptだけでできるようになるというのは、なかなか痛快です。

その後、指定YouTubeムービーのダウンロードも自由自在に行えるようになり、「戦場の絆」のリプレイ映像の保存がはかどることになりました。

2016/3/6「REST APIに対してGET、POST、PUT、DELETEのmethodを呼び出す」

ひととおりのmethodについてやり方をまとめておけたのはよかったと思います。今年一番いろいろいじくり回したプログラムです。

これがなければ、画像認識して顔エリアを切り出すとか、Dropboxにファイルをアップロードして公開期限&パスワードつきで共有するといった無茶な処理はできませんでした。

2016/4/5「質問を募集します」

技術書系同人誌即売会「技術書典」への参加を本Blog上で発表した最初の投稿です。つまり、AppleScript本を出すことの意思表明でもありました。ちなみに、2017年4月9日開催の「技術書典2」にもすでに参加を申し込んでいます(申し込んだだけなので、まだ正式に参加できるかは不明です)。

2016/4/30「技術系同人誌即売会「技術書典」B-01ブースにて出展」

書籍については、当初案から随分と(短い期間で)方向をいろいろ変えたもんだと驚きます。技術書典2(来年の4月9日開催)への申し込みをすでに行っていますが、新刊の内容は固まっています。

2016/4/30「WikipediaのAppleScriptの項目を大幅書き換え」

WikipediaのAppleScriptの項目を大改修したのがこの日でした。まったくの別物に仕上がり、アップデートにも成功し、なかなかよかったのではないかと。

2016/5/12「表計算ソフトの選択範囲のデータをMarkdown形式の表テキストに変換する」

ちょうど執筆で修羅場を見ていたころです。MacDownでいろいろ書き出してみて、Markdownだと「意外と作れないものが多い」ことに驚き、あわあわしていました。その一方で、作業の自動化を行うことで、繰り返し作業を省いてなんとか間に合わせることができました。

作業の省力化を(短い期間で)実現していなかったら、技術書典当日に本は間に合っていなかったと思います。

2016/6/16「技術書典で販売する本、目下大詰め(のはず)」

直前ギリギリまで内容を詰めていたので、この記事で告知したとおりの内容にはなっていませんでした(オマケ系)。深くおわびもうしあげます。

2016/6/18「指定フォルダ以下にあるMacDownとPages書類をソートしてPDFに書き出す」

これが作れなかったら、本が出なかったというぐらい重要なScriptです。

2016/7/4「delay命令のパラメータが0.001秒まで対応」

本を書くためにいろいろ調査を行いましたが、これには最高に驚かされました。

2016/7/27「PDFをページごとに分解してJPEGで保存する v2」

PDF版の書籍からePub版をお手軽に作るために作成したAppleScriptです。ePub版を取り急ぎ作る必要があったので。

2016/7/28「Bookフォルダリネーム」

これも、原稿整理のために必須のScriptです。各フォルダ名/ファイル名の先頭につけた整理用番号のリナンバーを行うもので、割と手作業で行ってしまっていたものを自動化してみました。効果絶大だったのですが、個人的なノウハウや癖に依存しているので、一般的かどうかは不明です。

2016/9/25「電子書籍購入者特典「Script Assistant Ver.1.0」」

電子書籍購入者特典の「Piyomaru Script Assistant Ver.1.0」。AppleScriptを書くのに補助用のAppleScriptの機能を利用する、というOS標準の機能をさらに拡充したもので、自分はこれがないと作業ができません。ただし、作成してから10年近く経過していたので、あまり使っていなかったScriptでアップデートの必要があるものが割とあり、アップデートに予想外の手間がかかりました、、、いまだと、また別のツールを作ってみたりするかもしれません。

2016/11/9「HTTPServerKitのじっけん」

機能限定版Webサーバーをdocrootを指定しつつ起動できる本Scriptは、そっけない見た目からは計り知れないほどの威力が期待できるものです。

2016/11/12「URLからクエリー部分を取り出してRecordに」

AppleScriptだけでOAuth2.0の認証を行うために作った部品がコレです。OAuth2.0認証ができるのとできないのとでは、実現できる機能にずいぶんと差が出てきます。これを実装できたおかげで、他のツールに依存せず、広域に配布するAppleScriptにクラウドAPI呼び出しの機能を盛り込むことができるわけで、大変にけっこうなことです。

2016/12/3「Yahoo! 逆住所ジオコーダAPIを呼び出す」

住所情報から緯度経度情報を取得する「住所ジオコーダ」、緯度経度情報から住所情報を取得する「逆住所ジオコーダ」。これらの処理をサードパーティのソフトウェアのインストールなしで行えるようになったことには意義深いものがあります。さらに、クラウドのAPIに依存しなくても処理できるようになるともっといいですね。

2016/12/26 Apitoreで指定単語の日本語Wikipedia中におけるDocument Frequencyを取得する

Apitoreの「Document Frequency」REST APIを呼び出して、指定した任意の単語が日本語Wikipediaの記事(を文章ごとに分解したもの)中で登場する頻度を算出するAppleScriptです。

母集団の文章数は、計算してみたところ本記事作成時点で101万程度です。日本語Wikipediaの内容はApitoreさんによるダンプ時点のものです。

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

登場頻度を求める母集団が、あくまで日本語Wikipediaであることに注意してください。また、「AppleScript」などの単語は「アップルスクリプト」などと日本語(カタカナ)で指定する必要があります。

本サンプルScriptでは「ガンダム」という単語が、日本語Wikipediaからダンプしたすべての文章の中で何回登場しているかを調べます。2,200の文章において「ガンダム」という単語が登場したという計算結果が得られました。「2,200項目」ではなく「2,200の文章」という点に注意が必要です。

つまり、日本語Wikipediaの全文を「世間全体」とみたてて、その中における登場頻度をカウントするということは、イコール「どのぐらい一般性があるか」という尺度をはかるということになります。ただ、Wikipedia自体の信頼性がどうかという話とか、アニメや声優に関する情報に偏りすぎといった問題についてはとくに考慮されていません。

AppleScript名:Apitoreで日本語WikipediaのDocument Frequencyを取得する
– Created 2016-12-26 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4371

set targWords to “ガンダム”

set reqURLStr to “https://api.apitore.com/api/16/documentfrequency/get”
set accessToken to retAccessToken() —Access Token
set aRec to {access_token:accessToken, |word|:targWords}
set aURL to retURLwithParams(reqURLStr, aRec) of me

set aRes to callRestGETAPIAndParseResults(aURL) of me
set aRESCode to (responseCode of aRes) as integer
set aRESTres to (json of aRes) as record

return aRESTres
–>  {startTime:”1482730271238″, word:”ガンダム”, endTime:”1482730271238″, documentFrequency:2200.0, log:”", processTime:”0″}

–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 retAccessToken()
  return “XXXXxxxX-xxxx-XXXx-xxxX-XxxxXxXxxXXx” –API Tore Access Token
end retAccessToken

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 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

★Click Here to Open This Script 

2016/12/26 ApitoreでURLの自動タグ付け(TFIDF版)

Apitoreの「URLタグ付け(tfidf)」REST APIを呼び出して、指定URLのテキスト取得→形態素解析→tf-idfの上位語の出力を行うAppleScriptです。使用している形態素解析エンジンはJavaベースの「Kuromoji」、DF(Document Frequency、文書頻度)計算にはDocument Frequency APIを使っているとのこと。

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

指定のURLのページの内容を取得して、文章を形態素解析し、品詞が名詞、動詞、形容詞、未知語に該当する単語について(日本語Wikipediaの文章をダンプしたものを母集団として)登場頻度の高いもの(代表語)を算出。Apitoreさんによれば「titleやh1などの強調目的で使われるタグ内の文章は多少重みを強くしています」とのこと。

Webブラウザの「お気に入り」に登録したURLに対してタグ付けを行い、どういった種類のページかを分類するといった用途が提案されています。Safariのブックマークについては~/Library/Safari/Bookmarks.plistを読めば取得できるので、割と手軽に処理できそうです。ただ、Bookmarkの中身は割と無秩序かつ膨大なものになっている場合が多いので、いきなり処理するとドツボに、、、、

プログラムリスト中の冒頭のURLパラメータを途中で分割していますが、Blogに掲載する際の体裁を整えることが目的であり、他意はありません。

AppleScript名:ApitoreでURLの自動タグ付け(TFIDF版)
– Created 2016-12-26 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4370

set targURL to “https://ja.wikipedia.org/wiki/%E3%83%9F%E3%83%BC” & “%E3%82%A2%E3%82%AD%E3%83%A3%E3%83%83%E3%83%88″

set reqURLStr to “https://api.apitore.com/api/20/url2label-tfidf/get”
set accessToken to retAccessToken() —Access Token
set aRec to {access_token:accessToken, |url|:targURL, num:“10″}
set aURL to retURLwithParams(reqURLStr, aRec) of me

set aRes to callRestGETAPIAndParseResults(aURL) of me
set aRESCode to (responseCode of aRes) as integer
set aRESTres to (json of aRes) as record

return aRESTres
(*
{labels:{{label:”ミーアキャット”, score:61.965260670581},
{label:”Wikipedia”, score:12.012157282861}, {label:”衣”, score:9.314981960042},
{label:”褐色”, score:9.100539792011}, {label:”毛”, score:8.272037820828},
{label:”生後”, score:7.871644293159}, {label:”上下”, score:7.450132056768},
{label:”灰白色”, score:6.988390560903}, {label:”属”, score:6.845039327791},
{label:”ヘルパー”, score:6.575153905126}},
input:”https://ja.wikipedia.org/wiki/%E3%83%9F%E3%83%BC%E3%82%A2%E3
%82%AD%E3%83%A3%E3%83%83%E3%83%88″,
endTime:”1482725908492″, processTime:”807″, log:”", startTime:”1482725907685″, num:”10″}
*)

–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 retAccessToken()
  return “XXXXxxxX-xxxx-XXXx-xxxX-XxxxXxXxxXXx” –API Tore Access Token
end retAccessToken

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 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

★Click Here to Open This Script 

2016/12/20 OgreKit.frameworkを呼び出して正規表現処理を行う

正規表現の機能を提供するOgreKit.framework(オウガキット)をAppleScriptから呼び出すじっけんです。
ogrekitlogo.png

ASOCを使い始めて真っ先にテストしていたのですが、当時はまだObjective-CからAppleScriptへの「翻訳」のスキルが高くなかったので動くようにできませんでした。さすがに今だと問題なく翻訳できます。

本AppleScriptを構文確認・実行するには、OgreKit.frameworkを~/Library/Frameworksフォルダに入れておく必要があります。ただし、OgreKit自体GitHubで配布されているソースをビルドするといいのか、どこかで配布されているバイナリを拾ってきたのか、入手経路についてはあまり記憶が定かではありません(けっこう放置していたので)。ちなみに、確認はバージョン2.0で行いました。

OgreKitをはじめCocoa+Objective-Cから使える正規表現のフレームワークは割といろいろ試していますが、テキストの抽出や置換が目的であって、GUIアプリケーション上のオブジェクトをこれで抽出できるというものではありません。そこはフィルタ参照を用いることになります。

AppleScript名:OgreKitで文字列中の正規表現にマッチした部分を順番に得る
– Created 2016-12-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OgreKit”
–http://piyocast.com/as/archives/4368
–http://sonoisa.github.io/ogrekit/HowToUse2.html

set regEx to current application’s OGRegularExpression’s regularExpressionWithString:“a[^a]*a”
set enum to regEx’s matchEnumeratorInString:“alphabetagammadelta”

set aResArray to current application’s NSMutableArray’s alloc()’s init()
repeat
  set aMatch to enum’s nextObject()
  
if aMatch = missing value then exit repeat
  
set hitStr to aMatch’s matchedString()
  
aResArray’s addObject:hitStr
end repeat

return aResArray as list
–>  {”alpha”, “aga”, “adelta”}

★Click Here to Open This Script 

AppleScript名:OgreKitで文字列を正規表現にマッチした部分で分割する
– Created 2016-12-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OgreKit”
–http://piyocast.com/as/archives/4368
–http://sonoisa.github.io/ogrekit/HowToUse2.html

set regEx to current application’s OGRegularExpression’s regularExpressionWithString:“\\s*,\\s*”
set dRes to (regEx’s splitString:“36.5C, 3.8C, -195.8C”) as list
–> {”36.5C”, “3.8C”, “-195.8C”}

★Click Here to Open This Script 

AppleScript名:OgreKitで文字列中の正規表現にマッチした部分すべてを置換する
– Created 2016-12-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OgreKit”
–http://piyocast.com/as/archives/4368
–http://sonoisa.github.io/ogrekit/HowToUse3.html

set regEx to current application’s OGRegularExpression’s regularExpressionWithString:“a[^a]*a”
set dRes to (regEx’s replaceAllMatchesInString:“alphabetagammadelta” withString:“(\\0)”) as string
–>  ”(alpha)bet(aga)mm(adelta)”

★Click Here to Open This Script 

AppleScript名:OgreKitでNSStringに対して検索を行い、最初にマッチした範囲を返す
– Created 2016-12-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OgreKit”
–http://piyocast.com/as/archives/4368
–http://sonoisa.github.io/ogrekit/HowToUse6.html

set aStr to current application’s NSString’s stringWithString:“alphabetagammadelta”
set matchedRange to aStr’s rangeOfRegularExpressionString:“a[^a]*a”
return matchedRange as record
–>  {location:0, length:5}

★Click Here to Open This Script 

AppleScript名:OgreKitでNSMutableStringに対して検索・置換を行う
– Created 2016-12-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OgreKit”
–http://piyocast.com/as/archives/4368
–http://sonoisa.github.io/ogrekit/HowToUse6.html

set aStr to current application’s NSMutableString’s stringWithString:“alphabetagammadelta”
aStr’s replaceOccurrencesOfRegularExpressionString:“a[^a]*a” withString:“(\\0)” options:1 range:(current application’s NSMakeRange(0, aStr’s |length|()))
aStr as string
–>  ”(alpha)bet(aga)mm(adelta)”

★Click Here to Open This Script 

AppleScript名:OgreKitで指定テキストファイルの改行コードを統一する
– Created 2016-12-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “OgreKit”
use textParser : script “japaneseTextEncodingDetector”
–http://piyocast.com/as/archives/4368
–http://sonoisa.github.io/ogrekit/HowToUse5.html

property OgreNonbreakingNewlineCharacter : -1 –(無改行)
property OgreUnixNewlineCharacter : 0 –LF(Unix)
property OgreLfNewlineCharacter : 0 –LF(Unix)
property OgreMacNewlineCharacter : 1 –CR(Mac)
property OgreCrNewlineCharacter : 1 –CR(Mac)
property OgreWindowsNewlineCharacter : 2 –CR+LF(Windows)
property OgreCrLfNewlineCharacter : 2 –CR+LF(Windows)

set aFile to POSIX path of (choose file)
set aText to readJapanesTextFileWithGuessingEncoding(aFile) of textParser –日本語テキストエンコーディング自動判定ライブラリで判定
set cText to current application’s OGRegularExpression’s replaceNewlineCharactersInString:aText withCharacter:OgreLfNewlineCharacter

★Click Here to Open This Script 

2016/12/17 ネットワークデバイスからactiveなものだけをピックアップする

ネットワークデバイスから、activeなものだけをピックアップするAppleScriptです。

DHCPのネットワークアドレスのリフレッシュを試みたときに、接続中のネットワークデバイス名が必要になるので、試しに作ってみました。

試作品レベルなので、実用性についてはいろいろ問題があります。

まず、ネットワーク接続が切れているとまともに動かないので、ネットワーク接続確認は別途行なっておく必要があります。

さらに、複数のネットワークインタフェース(USB-Ethernetアダプタと本体内蔵WiFiとか)がアクティブになっている場合の結果が正しいことは保証しません(まだ、このあたりの詰めが必要)。

本プログラムでは、複数返ってきた場合には最初の項目を返してくるので、自分のマシン環境でも「これはいかがなものか」という状態です(USB-Ethernetアダプタで有線接続しつつ、位置情報を取得するためにWiFiをオンにすることがあるので)。

正規表現の鬼のような人だと、もう少し美しく短いプログラムにまとめられると思います。自分が短く書くために選んだ道具はtext item delimiters。

text item delimitersに複数(2よりも多い複数)の項目を指定できるので、あらかじめ各デバイス情報の1行目だけをピックアップしておき、これをtext item delimitersに指定してifconfigの処理結果をリスト化し、欠けた各デバイス情報の1行目を順次補っていくという、かなり頭のおかしなプログラムです。

AppleScript名:ネットワークデバイスからactiveなものだけをピックアップする
– Created 2016-12-17 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4367

set aDevRes to getActiveNetworkInterfaceDeviceName() of me
set aDevName to devName of aDevRes
–>  ”en3″

–ifconfigからactiveなデバイス名だけをピックアップする
on getActiveNetworkInterfaceDeviceName()
  set aRes to (do shell script “ifconfig”)
  
set aList to paragraphs of aRes
  
  
set devNameList to {}
  
repeat with i in aList
    set j to contents of i
    
set bRes to regexMatches(j, “^[^\\t]*”) of me
    
if bRes is not equal to {{“”}} then
      set the end of devNameList to contents of item 1 of item 1 of bRes
    end if
  end repeat
  
  
–Parse ifconfig results by device name list
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to devNameList –かなりトリッキー
  
set tmpList to text items of aRes
  
set AppleScript’s text item delimiters to curDelim
  
  
–initialize
  
set bList to rest of tmpList –remove blank item at top
  
set aCount to 1
  
set aResList to current application’s NSMutableArray’s alloc()’s init()
  
  
repeat with i in bList
    set aCon to contents of i
    
set aDat to contents of item aCount of devNameList
    
–Device Name
    
set aDevName to retStrFromTopToAstr(aDat, “:”) of me
    
    
set bCon to paragraphs 2 thru -1 of aCon
    
set cCon to aDat & retDelimedText(bCon, return) of me
    
    
–Activeなdeviceを抽出するための条件付け
    
set activeF1 to cCon contains “status: active”
    
set activeF2 to cCon does not contain “media: autoselect (<unknown type>)”
    
    
set aRec to (current application’s NSDictionary’s dictionaryWithDictionary:{devName:aDevName, isActive:(activeF1 and activeF2), ifconfigRes:cCon})
    (
aResList’s addObject:aRec)
    
set aCount to aCount + 1
  end repeat
  
  
set activeIF to filterRecListByLabel(aResList, “isActive == [c]%@”, {true}) of me
  
(*
  {{devName:”en3″, ifconfigRes:”en3: flags=8863 mtu 1500\toptions=4\r\tether XX:Xx:xX:Xx:XX:xX \r\tinet6 xxXX::XxX:XXXX:XXXx:Xxxx%en3 prefixlen 64 secured scopeid 0×4 \r\tinet 192.168.0.5 netmask 0xffffff00 broadcast 192.168.0.255\r\tinet6 XXXx:XX:XXxX:X:xxX:XXXX:XXXx:XXxX prefixlen 64 autoconf secured \r\tinet6 XXXx:XX:XXxX:X:XXx:XXXX:XXXx:xXXx prefixlen 64 autoconf temporary \r\tnd6 options=201 \r\tmedia: autoselect (100baseTX )\r\tstatus: active”, isActive:true}}
*)
  return first item of activeIF –Multiple Device Name list may return. Now, I choose one.
end getActiveNetworkInterfaceDeviceName

–http://qiita.com/szk-3/items/8bbe841eb0295caee6b0
on regexMatches(aText as text, pattern as text)
  set regularExpression to current application’s NSRegularExpression’s regularExpressionWithPattern:pattern options:0 |error|:(missing value)
  
set aString to current application’s NSString’s stringWithString:aText
  
set matches to regularExpression’s matchesInString:aString options:0 range:{location:0, |length|:aString’s |length|()}
  
set matchResultList to {}
  
repeat with match in matches
    set mRes to {}
    
repeat with i from 0 to (match’s numberOfRanges as integer) - 1
      set end of mRes to (aString’s substringWithRange:(match’s rangeAtIndex:i)) as text
    end repeat
    
set end of matchResultList to mRes
  end repeat
  
return matchResultList
end regexMatches

–リストを指定デリミタを入れつつテキスト化
on retDelimedText(aList, aDelim)
  set aText to “”
  
set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set aText to aList as text
  
set AppleScript’s text item delimiters to curDelim
  
return aText
end retDelimedText

–先頭から指定キャラクタまでを抽出して返す
on retStrFromTopToAstr(aStr, aTarg)
  set aLen to length of aTarg
  
set anOffset to offset of aTarg in aStr
  
set bStr to text 1 thru (anOffset - aLen) of aStr
  
return bStr
end retStrFromTopToAstr

–リストに入れたレコードを、指定の属性ラベルの値で抽出(predicateとパラメータを分離)
on filterRecListByLabel(aRecList, aPredicate, aParam)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate argumentArray:aParam
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
set bList to filteredArray as list
  
return bList
end filterRecListByLabel

★Click Here to Open This Script 

2016/12/15 PDFしおり用データをNumbersから取得

PDFに「しおり」を作成する元のデータをNumbers上に記述しておくと、作成用のデータを取得・変換するAppleScriptです。構文確認および実行には、Shane Stanleyの「BridgePlus」AppleScript Libraries(フリー)のインストールを必要とします。

また、Numbersで(↓)のような書類を作成して、Numbersでオープンしていることが動作の前提条件です。

numbers_shiori.png

元のプログラムでは直接Script Editor上でレコードとして記述するのが、なかなか大変。また、親項目をタイトル文字列で記述するのも(作業時にミスりそうで)大変だったので、Numbers書類上で記述できるようにしてみたものです。

shiori.png

親項目は番号で記述するようにして、ID自体の連番の生成もAppleScriptから行い、極力作業ミスが発生しないように配慮してみました。

shiori2.png

AppleScript名:しおり用データをNumbersから取得
【コメント】 Book2_index_v2 を前提としています
– Created 2016-12-15 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use framework “Foundation”
use scripting additions
use BridgePlus : script “BridgePlus”
–http://piyocast.com/as/archives/4363

set aData to getIndexRecListFromNumbers() of me
–> {{|index|:3, title:”広告”, |parent|:”"}, {|index|:4, title:”本書購入特典のご案内”, |parent|:”"},…..

–NumbersのデータからPDFに付けるしおりのデータを取得する
on getIndexRecListFromNumbers()
  tell application “Numbers”
    tell window 1
      set aWinProp to properties
    end tell
    
    
set aDoc to document of aWinProp
    
tell aDoc
      tell active sheet
        tell table 1
          set colNum to column count
          
if colNum is not equal to 4 then error “Illegal Column Numbers”
          
set rowNum to row count
          
set vList to value of every cell
        end tell
      end tell
    end tell
  end tell
  
  
–Transform 1D array to 2D array
  
load framework
  
set tdList to (current application’s SMSForder’s subarraysFrom:(vList) groupedBy:colNum |error|:(missing value)) as list
  
–> {{”ID”, “index”, “title”, “parent”}, {1.0, 3.0, “広告”, missing value}, …..
  
  
–Skip First Row
  
set td2List to rest of tdList –first itemだけスキップする
  
  
set mokujiRecords to {}
  
repeat with i in td2List
    copy i to {anID, anIND, aTITLE, aParent}
    
    
–log {anID, anIND, aTITLE, aParent}
    
if aParent is not equal to missing value then
      set bParent to contents of item 3 of (item aParent of td2List)
    else
      set bParent to “”
    end if
    
    
set tmpRec to {|index|:(contents of anIND) as integer, title:aTITLE, |parent|:bParent}
    
set the end of mokujiRecords to tmpRec
  end repeat
  
  
return mokujiRecords
  
end getIndexRecListFromNumbers

★Click Here to Open This Script 

2016/12/14 レコードのうち、最大の値を持つKeyを返す

レコードのうち、最大の値を持つキーを返すAppleScriptです。

AppleScriptからMicrosoftの表情認識APIを呼び出せるようになったはいいものの、得られたデータからどの表情の可能性が高いかを判定する必要があり、そのために書いてみたものです。

Cocoaの機能を用いて、レコードのキーを取り出したり、さまざまな処理を行っています。こうした処理が手軽にできるようになったのは、実にいいことです。

さらに、画像から顔認識を行い、表情を読み取ってデータ化できるというのは、実に素晴らしいと思うものです。

ただ、いろいろ実験を行ってみたところ・・・恐れとか悲しみとか軽蔑といった微妙な感情については検出しづらいことがわかってきました。最大の値のものをピックアップするという方法ではなく、微妙な感情については別途評価を行う必要がありそうです。

mona_lisa_by_leonardo_da_vinci_from_c2rmf_retouched-1.jpg
–> “neutral”

donaldtrump61815_resized.png
–> “anger”

AppleScript名:レコードのうち、最大の値を持つKeyを返す
– Created 2016-12-14 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4359

set aDict to current application’s NSDictionary’s dictionaryWithDictionary:{sadness:0.01133416, anger:1.03975857E-4, happiness:2.90919736E-4, fear:2.28432211E-4, neutral:0.9830475, contempt:2.4698046E-4, disgust:1.02946949E-4, surprise:0.00464509334}
set aMacKey to retMaxValueKey(aDict) of me
–>  ”neutral”

on retMaxValueKey(aDict)
  set aValList to aDict’s allValues()
  
set maxVal to (sort1DNumList(aValList, false) of me)’s firstObject()
  
set keyList to (aDict’s allKeys()) as list
  
  
repeat with i in keyList
    set j to contents of i
    
set aTmp to (aDict’s valueForKey:j)
    
set aRes to compareNumerically(maxVal, aTmp) of me
    
if aRes = true then return j
  end repeat
  
  
return false
end retMaxValueKey

–Numerical Strings Compare
on compareNumerically(aText as text, bText as text)
  set aStr to current application’s NSString’s stringWithString:aText
  
return (aStr’s compare:bText options:(current application’s NSNumericSearch)) = current application’s NSOrderedSame
end compareNumerically

–1D List(数値)をsort / ascOrderがtrueだと昇順ソート、falseだと降順ソート
on sort1DNumList(theList, aBool)
  set theSet to current application’s NSSet’s setWithArray:theList
  
set theDescriptor to current application’s NSSortDescriptor’s sortDescriptorWithKey:(missing value) ascending:aBool
  
set sortedList to theSet’s sortedArrayUsingDescriptors:{theDescriptor}
  
return (sortedList)
end sort1DNumList

★Click Here to Open This Script 

2016/12/14 &と=で区切られたテキストをrecordに 改

「aParam=1234&bParam=2345」のように、URLのパラメータ部のような文字列を「&」と「=」で区切ってrecordとして出力するAppleScriptです。

「&と=で区切られたテキストをrecordに(NSScanner版)」をedama2さんがさらに改良したものです。

「先日掲載されたNSScannerのスクリプト、自分でも試してみてとても便利だったんですが、値なしの時にエラーになるので修正してみました。

あとリファレンス本に「repeat until」はあんまり使わないと書いてあったので使ってみました。(edama2さん)」

なるほど。たしかにラベルだけで値が存在しないケースに対応できるとよさそうです。

AppleScript名:&と=で区切られたテキストをrecordに 改
– Created 2016-12-12 by Shane Stanley
– Modified 2016-12-14 by edama2
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4358

set aParamStr to "access_token=XXxxx(XXxXXXXXxxXxxXXx))&expires=86399&name="
set aDict to (parseStrByAmpAndEqual(aParamStr) of me)
–>  {expires:"86399", |name|:"", access_token:"XXxxx(XXxXXXXXxxXxxXXx))"}

on parseStrByAmpAndEqual(aParamStr)
  set theScanner to current application’s NSScanner’s scannerWithString:aParamStr
  
set aDict to current application’s NSMutableDictionary’s |dictionary|()
  
  
repeat until (theScanner’s isAtEnd as boolean)
    – terminate check, return the result (aDict) to caller
    
set {theResult, theKey} to theScanner’s scanUpToString:"=" intoString:(reference)
    
    
– skip over separator
    
theScanner’s scanString:"=" intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:"&" intoString:(reference)
    
if theValue is missing value then set theValue to "" –>追加
    
    
– skip over separator
    
theScanner’s scanString:"&" intoString:(missing value)
    
    
aDict’s setObject:theValue forKey:theKey
  end repeat
  
  
return aDict as record
end parseStrByAmpAndEqual

★Click Here to Open This Script 

2016/12/13 顔認識結果のデータを加工

Microsoftの顔認識APIを呼び出して、その結果を加工して表情認識APIを呼び出すために、顔認識APIの実行結果を加工するAppleScriptです。

まだ表情認識APIは呼び出せていませんが、その途中で作ったものです。

典型的なデータ加工の処理なので、ほかにも(もう少しうまい)やり方がありそうです。

AppleScript名:顔認識結果のデータを加工
– Created 2016-12-13 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
–http://piyocast.com/as/archives/4357

set aList to current application’s NSArray’s arrayWithArray:{{faceId:"c49883a0-c4ee-4671-ad06-6f7f8370ab20", faceRectangle:{top:68, width:40, |left|:336, height:40}}, {faceId:"93459b48-4c19-4cc7-85e6-b38b8d0fc73b", faceRectangle:{top:81, width:38, |left|:92, height:38}}, {faceId:"9c796619-c654-47dd-b7b0-c382dc6bda84", faceRectangle:{top:63, width:38, |left|:214, height:38}}, {faceId:"94a2ceec-c089-494c-982e-a213579342b6", faceRectangle:{top:92, width:38, |left|:462, height:38}}, {faceId:"18e8dad0-fe46-4c5c-81c3-3ba483129512", faceRectangle:{top:89, width:37, |left|:700, height:37}}, {faceId:"4031f4bd-4e47-4050-89a0-f66e2e4e9142", faceRectangle:{top:45, width:37, |left|:570, height:37}}}

set aRes to retFaceArray(aList) of me
–>  "336,68,40,40;92,81,38,38;214,63,38,38;462,92,38,38;700,89,37,37;570,45,37,37"

on retFaceArray(aList)
  set a1Res to (aList’s valueForKeyPath:"faceRectangle.top") as list
  
set a2Res to (aList’s valueForKeyPath:"faceRectangle.width") as list
  
set a3Res to (aList’s valueForKeyPath:"faceRectangle.left") as list
  
set a4Res to (aList’s valueForKeyPath:"faceRectangle.height") as list
  
  
set aLen to length of a1Res
  
set aRes to {}
  
  
repeat with i from 1 to aLen
    set aLeft to (contents of item i of a3Res) as string
    
set aTop to (contents of item i of a1Res) as string
    
set aWidth to (contents of item i of a2Res) as string
    
set aHeight to (contents of item i of a4Res) as string
    
set tmpRes to aLeft & "," & aTop & "," & aWidth & "," & aHeight
    
set the end of aRes to tmpRes
  end repeat
  
  
set allRes to retStrFromArrayWithDelimiter(aRes, ";") of me
  
  
return allRes
end retFaceArray

–リストを指定デリミタをはさんでテキスト化
on retStrFromArrayWithDelimiter(aList, aDelim)
  set anArray to current application’s NSArray’s arrayWithArray:aList
  
set aRes to anArray’s componentsJoinedByString:aDelim
  
return aRes as text
end retStrFromArrayWithDelimiter

★Click Here to Open This Script 

2016/12/12 &と=で区切られたテキストをrecordに(NSScanner版)

「aParam=1234&bParam=2345」のように、URLのパラメータ部のような文字列を「&」と「=」で区切ってrecordとして出力するAppleScriptです。

Shane Stanleyから「NSScannerを使った実装例」を教えてもらいました。「高速ではないけど、NSSCannerは便利なクラスなので慣れておいたほうがいいよ」という実例です。

Cocoaには、AppleScriptの処理系にはまったく存在していない強力な機能があり、使うととても便利で、プログラムを短く書くことができ、圧倒的に高速処理が可能です。

 リスト項目のユニーク化:NSSet
 リスト項目のユニーク化と出現回数カウント:NSCountedSet
 リスト項目のユニーク化とソート:NSMutableIndexSet
 リスト項目のしぼりこみ:NSPredicate

など、もはやプログラムを書く上で「ないと困る!」というレベルの道具になっています。ファイルパスの加工が強力なNSStringもないと困るレベルのものです。

NSScannerについて、Shaneのプログラムをそのまま掲載するとこんな感じですが、これは「巨大なプログラムを書き慣れた人が書く」タイプのプログラムであり、個別に理解を深めようとすると・・・つまり、「教材」として提示する際には若干の清書が必要になります。

AppleScript名:&と=で区切られたテキストをrecordに(NSScanner Orig)
– Created 2016-12-12 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4356

set aParamStr to “access_token=XXxxx(XXxXXXXXxxXxxXXx))&expires=86399″
set aDict to (parseStrByAmpAndEqual(aParamStr) of me) as record

on parseStrByAmpAndEqual(aParamStr)
  set theScanner to current application’s NSScanner’s scannerWithString:aParamStr
  
set aDict to current application’s NSMutableDictionary’s |dictionary|()
  
repeat
    set {theResult, theKey} to theScanner’s scanUpToString:“=” intoString:(reference)
    
if theResult as boolean is false then return aDict
    
– skip over separator
    
theScanner’s scanString:“=” intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:“&” intoString:(reference)
    
– skip over separator
    
theScanner’s scanString:“&” intoString:(missing value)
    
aDict’s setObject:theValue forKey:theKey
  end repeat
end parseStrByAmpAndEqual

★Click Here to Open This Script 

自分が動作内容を確認するためには、こんな感じに

(1)意味を取りやすいように空行を追加
(2)プログラムの動きを理解しやすいように、さまざまな変数のログ表示を行う
(3)プログラムのInputとOutputがわかりやすいように、サンプルデータの処理結果を掲載

のように書き換えます。

AppleScript名:&と=で区切られたテキストをrecordに(NSScanner 2)
– Created 2016-12-12 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4356

set aParamStr to “access_token=XXxxx(XXxXXXXXxxXxxXXx))&expires=86399″
set aDict to (parseStrByAmpAndEqual(aParamStr) of me) as record
–>  {expires:”86399″, access_token:”XXxxx(XXxXXXXXxxXxxXXx))”}

on parseStrByAmpAndEqual(aParamStr)
  set theScanner to current application’s NSScanner’s scannerWithString:aParamStr
  
log (theScanner’s scanLocation())
  
  
set aDict to current application’s NSMutableDictionary’s |dictionary|()
  
repeat
    – terminate check, return the result (aDict) to caller
    
set {theResult, theKey} to theScanner’s scanUpToString:“=” intoString:(reference)
    
if theResult as boolean is false then return aDict
    
log (theScanner’s scanLocation())
    
    
– skip over separator
    
theScanner’s scanString:“=” intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:“&” intoString:(reference)
    
log (theScanner’s scanLocation())
    
    
– skip over separator
    
theScanner’s scanString:“&” intoString:(missing value)
    
    
aDict’s setObject:theValue forKey:theKey
    
log (theScanner’s scanLocation())
  end repeat
end parseStrByAmpAndEqual

★Click Here to Open This Script 

そして、最終的に確認用のコードを削除して(クリーニングして)、こういうリストを掲載しています。

AppleScript名:&と=で区切られたテキストをrecordに(NSScanner 1)
– Created 2016-12-12 by Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4356

set aParamStr to “access_token=XXxxx(XXxXXXXXxxXxxXXx))&expires=86399″
set aDict to (parseStrByAmpAndEqual(aParamStr) of me) as record
–>  {expires:”86399″, access_token:”XXxxx(XXxXXXXXxxXxxXXx))”}

on parseStrByAmpAndEqual(aParamStr)
  set theScanner to current application’s NSScanner’s scannerWithString:aParamStr
  
set aDict to current application’s NSMutableDictionary’s |dictionary|()
  
  
repeat
    – terminate check, return the result (aDict) to caller
    
set {theResult, theKey} to theScanner’s scanUpToString:“=” intoString:(reference)
    
if theResult as boolean is false then return aDict
    
    
– skip over separator
    
theScanner’s scanString:“=” intoString:(missing value)
    
set {theResult, theValue} to theScanner’s scanUpToString:“&” intoString:(reference)
    
    
– skip over separator
    
theScanner’s scanString:“&” intoString:(missing value)
    
    
aDict’s setObject:theValue forKey:theKey
  end repeat
end parseStrByAmpAndEqual

★Click Here to Open This Script 

2016/12/09 &と=で区切られたテキストをrecordに

「aParam=1234&bParam=2345」のように、URLのパラメータ部のような文字列を「&」と「=」で区切ってrecordとして出力するAppleScriptです。

とあるWeb APIでOAuth認証を呼び出してアクセストークンを取得したら、こんな形式の文字列で返してきた偏屈なもの(Stack ExchangeのAPI)があったので、対処のために作成したものです。

よく作る(作り捨てする)タイプの処理なので、たぶん何度も書いていると思います、、、、

AppleScript名:&と=で区切られたテキストをrecordに
– Created 2016-12-09 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4355

set aParamStr to “access_token=XXxxx(XXxXXXXXxxXxxXXx))&expires=86399″
set aDict to (parseStrByAmpAndEqual(aParamStr) of me) as record
–> {expires:”86399″, access_token:”XXxxx(XXxXXXXXxxXxxXXxx))”}

on parseStrByAmpAndEqual(aParamStr)
  set aStr to current application’s NSString’s stringWithString:aParamStr
  
set aList to (aStr’s componentsSeparatedByString:“&”) as list
  
set aDict to current application’s NSMutableDictionary’s alloc()’s init()
  
  
repeat with i in aList
    set j to (current application’s NSString’s stringWithString:(contents of i))
    
set {aLabel, aValue} to (j’s componentsSeparatedByString:“=”)
    (
aDict’s setValue:aValue forKey:aLabel)
  end repeat
  
  
return aDict
end parseStrByAmpAndEqual

★Click Here to Open This Script 

2016/12/09 gooの形態素解析APIを呼び出す

gooラボが公開している各種APIのうちの、形態素解析APIを呼び出して日本語をparseするAppleScriptです。


supported by goo

利用にあたっては、gooラボAPI利用方法のページからのリンクで、Githubのアカウントを用いて(先に、Githubのアカウントを取得してある必要がある)ひもづけして(リンクをクリックするとひもづけ完了)、Application IDを取得。取得したIDをScript中に記入しておく必要があります。

gooのAPIは見た限りではみんなPOST methodを使って情報をAPIに受け渡す必要があり、少々クセがあります。ただし1つ攻略できてしまえば全部攻略できたも同じ。難易度はそれほど高くはありません(全API攻略済み)。

gooが提供しているAPIの機能レベルについては「他より頑張っている」印象。

 キーワード抽出API:面白いけど、固有名詞辞書の内容次第

 ひらがな化API:ただしい「読み」のひらがなにできるかは固有名詞辞書次第

 固有表現抽出API:

 語句類似度算出API:ウィンドウズとWindows程度の類似度は分かるが、実際に関連性がありそうな単語同士の関連性がそれほど高く評価されない。Apitoreの「単語ベクトル変換【新語対応】」(word2vec)の方が使える印象

 時刻情報正規化API:10年以上前にAppleScriptで作った気がする。ただ、こうして提供されているのは便利だし意義深い

 商品評判要約API:実用性の高そうな要約エンジンは必要。どの程度の長文の要約に耐えられるかがみどころ。実用性は未知数

当の形態素解析APIについては、Webサービスの常で、イレギュラーな人名などの固有名詞を正確に認識することは困難なようです。逆に、Yahoo!の形態素解析辞書に「長野谷」という名前が登録されていること自体が異例といえるでしょう。

AppleScript名:Gooの形態素解析APIを呼び出す
– Created 2016-12-08 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.5″
use scripting additions
use framework “Foundation”
–https://labs.goo.ne.jp/api/jp/morphological-analysis/
–http://piyocast.com/as/archives/4354

set anID to retAPIKey() of me

set reqURLStr to “https://labs.goo.ne.jp/api/morph”
set aPostData to {request_id:“record001″, sentence:“私の名前は長野谷です。”, app_id:anID}
set aRes to callRestPOSTAPIAndParseResults(reqURLStr, aPostData) of me
set aRESCode to (responseCode of aRes) as integer
if aRESCode is not equal to 200 then return false

set aRESHeader to responseHeader of aRes
set aRESTres to json of aRes
–>  (NSDictionary) {request_id:”record001″, word_list:{{{”私”, “名詞”, “ワタシ”}, {”の”, “格助詞”, “ノ”}, {”名前”, “名詞”, “ナマエ”}, {”は”, “連用助詞”, “ハ”}, {”長野”, “名詞”, “ナガノ”}, {”谷”, “名詞接尾辞”, “ダニ”}, {”です”, “判定詞”, “デス”}, {”。”, “句点”, “$”}}}}

–POST methodのREST APIを呼ぶ
on callRestPOSTAPIAndParseResults(aURL, aPostData)
  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 & 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 callRestPOSTAPIAndParseResults

on retAPIKey()
  return “XXxXXxXXxXxxxXXXxXXxXxXxXXxXxXXXxXxXxxxXxXXXXxXxxXXXxXXXxXXXXxXX” –Goo API Key
end retAPIKey

★Click Here to Open This Script 

2016/12/08 GameplayKitを使ったリストのシャッフル

Shane Stanleyから教えてもらった、GameplayKitを用いた高速なリストのシャッフルScriptです。ただし、実行にはmacOS 10.12を必要とします。

9999項目のリストをシャッフルする処理で、DCRandomizeを使ったScriptで0.02秒、本Script(GameplayKitのshuffledArray())では0.427秒かかりました(10回実行時の平均値)。

本Scriptでも9999項目のNSMutableArrayの作成部分だけ取り出して計測すると0.405秒かかっているので、シャッフル部分は0.02秒程度です。

AppleScript名:GameplayKitを使ったリストのシャッフル
– Created 2016-12-08 by Shane Stanley
use AppleScript version “2.5″
use framework “Foundation”
use framework “GameplayKit”
use scripting additions
–http://piyocast.com/as/archives/4353

set anArray to current application’s NSArray’s arrayWithArray:{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
set newArray to anArray’s shuffledArray() as list – requires macOS 10.12

★Click Here to Open This Script 

AppleScript名:GameplayKitを使ったリストのシャッフル(計測用)
– Created 2016-12-08 by Shane Stanley
– Modified 2016-12-08 by Takaaki Naganoya
use AppleScript version “2.5″
use framework “Foundation”
use framework “GameplayKit”
use scripting additions
–http://piyocast.com/as/archives/4353

set anArray to current application’s NSMutableArray’s alloc()’s init()
repeat with i from 1 to 10000
  (anArray’s addObject:i)
end repeat

set newArray to anArray’s shuffledArray() as list – requires macOS 10.12

★Click Here to Open This Script 

AppleScript名:リストのシャッフル(計測用)
– Created 2016-12-06 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ArrayRandomize” –https://github.com/masakihirokawa/objc-classes-dc-randomize
–http://piyocast.com/as/archives/4353

–1〜9999の数値をシャッフルして配列取得
set cArray to (current application’s DCRandomize’s shuffle:1 max:9999) as list

★Click Here to Open This Script 

2016/12/07 リスト項目のシャッフル(ASOC)

リスト項目のシャッフルを行うAppleScriptです。オープンソースの「objc-classes-dc-randomize」をフレームワーク化した「ArrayRandomize」フレームワークを呼び出してシャッフルしています。

AppleScriptだけで作成した9999項目のリストのシャッフルと比べて、5,000倍ぐらい高速です(Objective-C側で処理した内容をただlistに変換しているだけなので)。本フレームワークを使うと、9999項目のリストのシャッフル生成で0.018秒(MacBook Pro Retina 2012 Core i7 2.66GHz)でした。

# ただ、比較対象のPure AppleScriptのプログラムも、まだまだ高速化の余地があったので、実際にはもう少し(10%ぐらい?)差は小さいと思います。Pure AppleScriptでも1,000項目ぐらいだと1秒ぐらいで処理が終わるのですが、、、ただ乱数を配列に追加するだけでなく、存在チェックと乱数の再生成を行うので、なかなかASには負荷が高い処理です

ArrayRandomize.frameworkをmacOS 10.10以降用にビルドしたバイナリを用意しましたので、自己責任で~/Library/Frameworksフォルダに入れて使って使ってみてください。

→ フレームワーク(19KB)のダウンロード

AppleScript名:リスト項目のシャッフル(ASOC)
– Created 2016-12-06 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ArrayRandomize” –https://github.com/masakihirokawa/objc-classes-dc-randomize
–http://piyocast.com/as/archives/4351

–配列をシャッフルして取得
set anArray to current application’s NSMutableArray’s alloc()’s initWithArray:{1, 2, 3, 4, 5}
set bArray to (current application’s DCRandomize’s shuffleArray:anArray) as list
–>  {5, 3, 1, 2, 4}

–1〜10の数値をシャッフルして配列取得
set cArray to (current application’s DCRandomize’s shuffle:1 max:10) as list
–>  {9, 4, 6, 5, 3, 2, 7, 8, 1, 10}

–5〜10の範囲の乱数を取得
set dArray to (current application’s DCRandomize’s range:5 max:10) as integer
–>  7

–5〜10の範囲で 9以外の乱数を取得
set eArray to (current application’s DCRandomize’s exact:5 max:10 exceptId:9)
–>  9

★Click Here to Open This Script 

2016/12/06 表インタフェースのダイアログを表示するライブラリ「Myriad Tables Lib」

Shane StanleyのAppleScript Librariesの最新版「Myriad Tables Lib」バージョン1.0.6が公開されました。こちらからダウンロードできるようになっています。

作ろうとすると割と手間がかかる表インタフェースがこうして手軽に呼び出せると、便利なケースが多いのではないでしょうか?

本バージョンのアップデート項目に「Japanese localization」という項目があり、どのあたりか分からなかったのですが、ボタンのタイトルが「Cancel」→「キャンセル」になっているあたりとか、表示用フォントのあたりなんでしょうか。

* Ability to show cells containing more than one line;
→ 複数行のテキストを含むセルを表示する機能(改行で区切ってある必要がある。セル幅で自動折り返しをしたりはしない)

* Ability to hide the Cancel button;
→ 「キャンセル」ボタンを隠す機能

* Improved handling of threading issues with accessory views;
→ アクセサリビューまわりのスレッドの取り扱いを向上させた(アクセサリビューのクリックイベントを受信できる)

* Ability to specify monospaced digits (10.11 and later only);
→ macOS 10.11以降で、等幅文字で数値の見た目をそろえる機能を追加

* Ability to have negative numbers appear in red;
→ マイナスの数値を赤で表示する機能を追加

* Ability to have column(s) appear in bold;
→ 指定カラムをボールド(太字)で表示する機能を追加

* Japanese localization.
→ 日本語環境に合わせたローカライズ

添付のサンプルScriptの実行例は以下のような感じです(処理内容抜粋)。

mtable1.png

mtable2_resized.png

mtable3.png

mtable4.png

mtable5.png

mtable6.png

2016/12/05 IPIFYで自分のグローバルIPアドレスを取得

ipfy.orgを呼び出して、グローバルIPアドレスを取得するAppleScriptです。

以前に掲載した「自分の(インターネットアクセス時の)IPアドレスを調べる」と同じ働きをするものです。

同じ結果が得られることを確認していますが、こちらの方が高速にアドレスを取得できています。

AppleScript名:IPIFYで自分のグローバルIPアドレスを取得
– Created 2016-12-04 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4343

set reqURLStr to “https://api.ipify.org”
set aRec to {|format|:“json”}
set aURL to retURLwithParams(reqURLStr, aRec) of me

set aRes to callRestGETAPIAndParseResults(aURL) of me
set aRESCode to (responseCode of aRes) as integer
if aRESCode is not equal to 200 then error “Server Error”

set aRESHeader to responseHeader of aRes
set aRESTres to |ip| of ((json of aRes) as record)

–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”
  
  
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 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

★Click Here to Open This Script 

2016/12/05 MOSA Tech MeetingレポートがMOSAのサイトに掲載されました

10月19日に渋谷で行われたMOSA Tech MeetingのレポートがMOSAのWebサイトに掲載され、ぴよまるソフトウェアがデモを行った様子をレポートしていただきました。

この日はiPhone 5のバッテリーが落ちまくってしまい、駅から10分程度の場所にある会場に1時間ぐらいかかって迷いながら走ってたどり着き、汗ダラダラのボロボロの状態でした(これで懲りてiPhone 5→iPhone 7に切り替え)。

あの日、土地勘のない夜の渋谷の街を駆け回って、諦めずに会場にたどり着いた自分を褒めてあげたい(^ー^;

発表に使ったスライドはこちらです

2016/12/05 アニメーションGIFをフレームごとに画像に分解する

アニメーションGIFを指定すると、指定フォルダ内にフレームごとに個別の連番GIF画像に分解出力するAppleScriptです。

AppleScript名:アニメーションGIFをフレームごとに画像に分解する
– Created 2016-11-29 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “AppKit”
–http://piyocast.com/as/archives/4341

set gifFile to POSIX path of (choose file of type “com.compuserve.gif” with prompt “Select Animation-GIF file”)
set destFol to POSIX path of (choose folder with prompt “Select the folder to save gif’s frames”)

set anImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:gifFile
if anImage is equal to missing value then error “Illegal GIF Image”

set anImgRep to anImage’s representations()’s firstObject()
set framesNum to (anImgRep’s valueForProperty:“NSImageFrameCount”) as integer

repeat with i from 0 to (framesNum - 1)
  (anImgRep’s setProperty:“NSImageCurrentFrame” withValue:i)
  
set aRep to (anImgRep’s representationUsingType:(current application’s NSGIFFileType) |properties|:(missing value))
  (
aRep’s writeToFile:(destFol & (i as string) & “.gif”) atomically:true)
end repeat

★Click Here to Open This Script 

2016/12/03 Yahoo! 逆住所ジオコーダAPIを呼び出す

Yahoo!の逆住所ジオコーダAPIで、緯度経度情報から住所情報を取得する(逆住所ジオコーディング、reverse geocoding)AppleScriptです。

Yahoo!に開発者登録(無料)して、アプリケーションIDを取得し、リスト中のretAccessKey()ハンドラにアプリケーションIDを記入すると実行可能です。

番地表記までの詳細な住所情報を取得できますが、天気予報の情報を検索するために都道府県(prefecture)と区市(city)の情報のみ取り出しています。

AppleScript名:Yahoo! 逆住所ジオコーダAPIを呼び出す
– Created 2016-11-20 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.5″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4340

–http://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/reversegeocoder.html

set aLat to 35.74 as string
set aLon to 139.6 as string
set aResList to reverseGeoCoderByYahoo(aLat, aLon) of me
–>  {”東京都”, “練馬区”}

on reverseGeoCoderByYahoo(aLat, aLon)
  set reqURLStr to “http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder”
  
set aKey to retAccessKey() of me
  
set aRec to {lat:aLat, lon:aLon, output:“json”, appid:aKey, datum:“tky”} –日本測地系
  
set aURL to retURLwithParams(reqURLStr, aRec) of me
  
set aRes to callRestGETAPIAndParseResults(aURL) of me
  
  
set aRESCode to responseCode of aRes
  
if aRESCode is not equal to 200 then return false
  
set aRESHeader to responseHeader of aRes
  
  
set aJSONres to (json of aRes)
  
set anAddress to (aJSONres’s valueForKeyPath:“Feature.Property”)’s firstObject()
  
set anElement to anAddress’s valueForKeyPath:“AddressElement”
  
  
set aPrefecture to first item of (my filterRecListByLabel1(anElement, “Level == ’prefecture’”))
  
–>  {Kana:”とうきょうと”, Name:”東京都”, Level:”prefecture”, Code:”13″}
  
  
set aCity to first item of (my filterRecListByLabel1(anElement, “Level == ’city’”))
  
–>  {Kana:”ねりまく”, Name:”練馬区”, Level:”city”, Code:”13120″}
  
  
set aPref to |Name| of aPrefecture
  
set aCt to |Name| of aCity
  
return {aPref, aCt}
end reverseGeoCoderByYahoo

–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”
  
  
–CALL REST API
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
  
–Parse Results
  
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 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 retAccessKey()
  return “xxXxxxXxXXxxxXXXXXXXXXXXXXXxXXXxxxXXxXXxxXXxxxXXXxxXXXX-” –Yahoo! API Key
end retAccessKey

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

–リストに入れたレコードを、指定の属性ラベルの値で抽出
on filterRecListByLabel1(aRecList as list, aPredicate as string)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
set bList to filteredArray as list
  
return bList
end filterRecListByLabel1

★Click Here to Open This Script 

2016/12/03 Yahoo! 住所ジオコーダAPIを呼び出す

Yahoo!の住所ジオコーダAPIで、指定の住所情報から緯度経度情報を取得する(住所ジオコーディング)AppleScriptです。

Yahoo!に開発者登録(無料)して、アプリケーションIDを取得し、リスト中のretAccessKey()ハンドラにアプリケーションIDを記入すると実行可能です。

AppleScript名:Yahoo! 住所ジオコーダAPIを呼び出す
– Created 2016-12-02 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.5″
use scripting additions
use framework “Foundation”
–http://piyocast.com/as/archives/4339

–http://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/geocoder.html

set anAddress to “東京都港区六本木6丁目10番1号”
set aResList to addressGeoCoderByYahoo(anAddress) of me
–>  {”35.66042757″, “139.72918139″}

on addressGeoCoderByYahoo(addrStr)
  set reqURLStr to “http://geo.search.olp.yahooapis.jp/OpenLocalPlatform/V1/geoCoder”
  
set aKey to retAccessKey() of me
  
set aRec to {query:addrStr, output:“json”, appid:aKey, datum:“tky”} –日本測地系
  
set aURL to retURLwithParams(reqURLStr, aRec) of me
  
set aRes to callRestGETAPIAndParseResults(aURL) of me
  
  
set aRESCode to responseCode of aRes
  
if aRESCode is not equal to 200 then return false
  
set aRESHeader to responseHeader of aRes
  
  
set aJSONres to (json of aRes)
  
  
set anAdd1 to (aJSONres’s valueForKeyPath:“Feature”)’s firstObject()
  
set aGPSstr to (anAdd1’s valueForKeyPath:“Geometry.Coordinates”)
  
set {aLon, aLat} to separateStrByAMark(aGPSstr, “,”) of me
  
  
return {aLat, aLon}
end addressGeoCoderByYahoo

–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”
  
  
–CALL REST API
  
set aRes to current application’s NSURLConnection’s sendSynchronousRequest:aRequest returningResponse:(reference) |error|:(missing value)
  
  
–Parse Results
  
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 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 retAccessKey()
  return “xxXxxxXxXXxxxXXXXXXXXXXXXXXxXXXxxxXXxXXxxXXxxxXXXxxXXXX-” –Yahoo! API Key
end retAccessKey

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

–リストに入れたレコードを、指定の属性ラベルの値で抽出
on filterRecListByLabel1(aRecList as list, aPredicate as string)
  set aArray to current application’s NSArray’s arrayWithArray:aRecList
  
set aPredicate to current application’s NSPredicate’s predicateWithFormat:aPredicate
  
set filteredArray to aArray’s filteredArrayUsingPredicate:aPredicate
  
set bList to filteredArray as list
  
return bList
end filterRecListByLabel1

–テキストを指定記号を元に分割する
on separateStrByAMark(aStr as string, aMark as string)
  set aMarkLen to length of aMark
  
set aOffset to offset of “,” in aStr
  
set aPart to text 1 thru (aOffset - 1) of aStr
  
set bPart to text (aOffset + aMarkLen) thru -1 of aStr
  
return {aPart, bPart}
end separateStrByAMark

★Click Here to Open This Script 

2016/12/01 現在位置の住所を取得する

Location Helperを利用して(Assisted GPS)現在のGPS座標を取得し、GPS座標をもとに住所を取得するAppleScriptです。

実行時にはWiFiによるネットワーク接続を行なっていることが必要です。Location HelperはMac AppStoreで無料で配布されています。

現在位置の取得についてはAppleScriptだけで(Location Helperを使わずに)行うこともできるわけですが、手軽ということでいえば圧倒的にLocation Helperです。

ただし、Location HelperはGoogleのWebサービスを呼び出しているため、連続して何度も(短時間に)呼び出すと、ペナルティが発生する可能性があります。また、Location Helper自体を勝手に再配布できないため、個人的にはなるべくこれに依存しないように書いています(客先に納品するという概念が存在しない場所では関係のない話です)。

とはいうものの、緯度経度情報から住所を取得する「逆住所ジオコーディング」についてはLocation Helperに頼る必要があるので、とりあえず一番簡単な記述を行なってみました。

ちなみに、Location Helperは不可視プロセスで実行されるため、Dock上にアイコンが表示されたりしません。AppleScriptから呼び出すための専用ツールです。

問い合わせを行なった結果は、同じ住所情報が異なる表現方法で11パターンほど返ってきました。ここに掲載できないほどズバリの住所が返ってくるので、実際に役に立つものと思われます。

AppleScript名:現在位置の住所を取得する
– Created 2016-12-01 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
–http://piyocast.com/as/archives/4338

tell application “Location Helper”
  set {aLat, aLong} to get location coordinates
  
set aRes to reverse geocode location {aLat, aLong}
end tell

★Click Here to Open This Script