Menu

Skip to content
AppleScriptの穴
  • Home
  • Products
  • Books
  • Docs
  • Events
  • Forum
  • About This Blog
  • License
  • 仕事依頼

AppleScriptの穴

Useful & Practical AppleScript archive. Click '★Click Here to Open This Script' Link to download each AppleScript

月: 2020年3月

NSURLSessionでREST API呼び出しv4.4

Posted on 3月 29, 2020 by Takaaki Naganoya

REST API呼び出しに欠かせない部品をアップデートしました。

–> GET method REST API v4.3
–> GET method REST API v4.1
–> GET method REST API v4

従来、NSURLConnectionを使って同期処理を行っていましたが、これがDepreceted扱いになりました。すぐになくなることはありませんが、いつかなくなる可能性があります。

このため、NSURLConnectionから動作原理の異なるNSURLSessionを使うよう移行する必要があります(curlコマンドを利用するというルートもあります)。

とはいえ、blocks構文の使えないAppleScriptでこのNSURLSessionを使えるようにするのは大変です。非同期通信を行うNSURLSessionを非同期処理のしにくいAppleScriptで、同期処理っぽく書かなくてはなりません。

NSURLSessionによる通信では、サーバーとの間で何回かのやりとりがあって、データを小分けに複数回受信する必要がありました。NSMutableDataというオブジェクトの存在を知ったのでいい感じに処理できるようになってきました。

NSURLSessionのメリットとして喧伝されている非同期処理は、AppleScriptから呼び出しているかぎりはそれほどメリットになりません。もう少し使い込めば活用できるかもしれませんが、まだそういう段階にはありません。

NSURLSessionの導入によって得られるメリットで最大のものは、キャッシュ機構です。NSURLConnectionでもキャッシュ機構は利用できましたが、NSURLSessionではよりAPIに深く統合されているものと理解しました。

キャッシュの効き方については、設定で何段階かに設定できるとAppleのオンラインドキュメントに書かれています。本Scriptでは、キャッシュ優先でキャッシュが存在している場合にはキャッシュ内のデータを返し、キャッシュが存在していない場合にはWebサーバーに問い合わせを行うように設定しています。

キャッシュが効いている状況なら、NSURLConnectionで1.8秒ぐらいの処理がNSURLSessionで0.1秒程度と大幅に速く処理できます。キャッシュが効いていない状況(初回実行時)だと、NSURLSessionのほうがやや処理に時間がかかるぐらいです。

処理結果について、NSURLConnection版とNSURLSession版で結果の比較を行ってみましたが、とくに差異は見られませんでした。

本サンプルScriptでは、Wikipedia(英語版)へのキーワードの問い合わせを行います。NSURLConnection版では複数回実行しても同じぐらいの速度で実行されますが、NSURLSession版では2度目から早く終わります(Script Debugger上で動かすと秒以下の精度の時間がわかります)。

macOS 10.14上で作ってmacOS 10.14.6/10.13.6上で動作確認しています(スクリプトエディタ、Script Debuggerで動作確認)。ただし、macOS 10.15上だとクラッシュします。Xcodeのプロジェクトに入れてみましたが、同様にmacOS 10.15上ではクラッシュします。

ただし、自分のmacOS 10.14.6環境はSIP解除しているのと、macOS 10.15環境のクラッシュログにSIP関連のメッセージが残っているので、OSバージョンではなくSIPのためかもしれません(macOS 10.14.6でもSIPを有効にするとクラッシュするかもしれない & macOS 10.15.xでもSIPを無効にするとクラッシュしないかもしれない)。

AppleScript名:GET method REST API v4.4_wikipedia
— Created 2019-05-02 by Takaaki Naganoya
— Modified 2020-03-29 by Takaaki Naganoya
— 2020 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property |NSURL| : a reference to current application’s |NSURL|
property NSString : a reference to current application’s NSString
property NSURLSession : a reference to current application’s NSURLSession
property NSMutableData : a reference to current application’s NSMutableData
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSMutableURLRequest : a reference to current application’s NSMutableURLRequest
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding
property NSURLSessionConfiguration : a reference to current application’s NSURLSessionConfiguration

property retData : missing value
property retCode : 0
property retHeaders : 0
property drecF : false

set aQueryKeyTitle to "Steve Jobs" –キーワードの正規化が必要("戦場の絆"→"機動戦士ガンダム 戦場の絆" )
set reqURLStr to "https://en.wikipedia.org/w/api.php"
set aRec to {action:"parse", page:aQueryKeyTitle, |prop|:"wikitext", format:"json"}
set aURL to retURLwithParams(reqURLStr, aRec) of me

set aRes to callRestGETAPIAndParseResults(aURL, 10) of me
set bRes to (aRes’s valueForKeyPath:"parse.wikitext.*") as string
return bRes

–GET methodのREST APIを呼ぶ
on callRestGETAPIAndParseResults(reqURLStr as string, timeoutSec as integer)
  set (my retData) to NSMutableData’s alloc()’s init()
  
set (my retCode) to 0
  
set (my retHeaders) to {}
  
set (my drecF) to false
  
  
set aURL to |NSURL|’s URLWithString:reqURLStr
  
set aRequest to NSMutableURLRequest’s requestWithURL:aURL
  
aRequest’s setHTTPMethod:"GET"
  
aRequest’s setTimeoutInterval:timeoutSec
  
aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding"
  
aRequest’s setValue:"AppleScript/Cocoa" forHTTPHeaderField:"User-Agent"
  
aRequest’s setValue:"application/json; charset=UTF-8" forHTTPHeaderField:"Content-Type"
  
  
set aConfig to NSURLSessionConfiguration’s defaultSessionConfiguration()
  
aConfig’s setRequestCachePolicy:(current application’s NSURLRequestReturnCacheDataElseLoad)
  
set aSession to NSURLSession’s sessionWithConfiguration:aConfig delegate:(me) delegateQueue:(missing value)
  
set aTask to aSession’s dataTaskWithRequest:aRequest
  
  
aTask’s resume() –Start URL Session
  
  
repeat (10 * timeoutSec) times
    if (my drecF) = true then
      exit repeat
    end if
    
delay 0.1
  end repeat
  
  
return my parseSessionResults()
end callRestGETAPIAndParseResults

on URLSession:tmpSession dataTask:tmpTask didReceiveData:tmpData
  (my retData)’s appendData:tmpData
end URLSession:dataTask:didReceiveData:

on URLSession:tmpSession dataTask:tmpTask didCompleteWithError:tmpError
  set (my drecF) to true
end URLSession:dataTask:didCompleteWithError:

on URLSession:tmpSession dataTask:tmpTask willCacheResponse:cacheRes completionHandler:aHandler
  set (my drecF) to true
end URLSession:dataTask:willCacheResponse:completionHandler:

on parseSessionResults()
  set resStr to NSString’s alloc()’s initWithData:(my retData) encoding:(NSUTF8StringEncoding)
  
set jsonString to NSString’s stringWithString:(resStr)
  
set jsonData to jsonString’s dataUsingEncoding:(NSUTF8StringEncoding)
  
set aJsonDict to NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value)
  
return aJsonDict
end parseSessionResults

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 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, missing value}
  
return bList
end filterRecListByLabel1

★Click Here to Open This Script 

AppleScript名:GET method REST API_wikipedia
— Created 2016-03-03 by Takaaki Naganoya
— 2016 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"

set aQueryKeyTitle to "Steve Jobs" –キーワードの正規化が必要("戦場の絆"→"機動戦士ガンダム 戦場の絆" )
set reqURLStr to "https://en.wikipedia.org/w/api.php"
set aRec to {action:"parse", page:aQueryKeyTitle, |prop|:"wikitext", format:"json"}
set aURL to retURLwithParams(reqURLStr, aRec) of me

set aRes to callRestGETAPIAndParseResults(aURL, 10) of me
set aRESTres to json of aRes
set bRes to (aRESTres’s valueForKeyPath:"parse.wikitext.*") as string

–GET methodのREST APIを呼ぶ
on callRestGETAPIAndParseResults(aURL, timeoutSec)
  set aRequest to current application’s NSMutableURLRequest’s requestWithURL:(current application’s |NSURL|’s URLWithString:aURL)
  
aRequest’s setHTTPMethod:"GET"
  
aRequest’s setTimeoutInterval:timeoutSec
  
aRequest’s setValue:"gzip" forHTTPHeaderField:"Content-Encoding"
  
aRequest’s setValue:"AppleScript/Cocoa" forHTTPHeaderField:"User-Agent"
  
aRequest’s setValue:"application/json; charset=UTF-8" 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 (dRes’s statusCode()) as integer
  
  
–Get Response Header
  
set resHeaders to (dRes’s allHeaderFields()) as record
  
  
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 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 

(Visited 82 times, 1 visits today)
Posted in Internet REST API URL | Tagged 10.13savvy 10.14savvy NSArray NSJSONSerialization NSMutableData NSMutableDictionary NSMutableURLRequest NSPredicate NSString NSURL NSURLComponents NSURLQueryItem NSURLSession NSURLSessionConfiguration NSUTF8StringEncoding | 2 Comments

マウスカーソルを変更

Posted on 3月 24, 2020 by Takaaki Naganoya

Xcode上で記述するAppleScriptアプリケーションにおいて、マウスカーソルを変更するAppleScriptです。

NSCursorにアクセスして、macOS側で用意しているカーソルにマウスカーソルのイメージを変更します。

–> Watch Demo Movie

あらかじめmacOSが用意しているカーソルはいくつかあるわけですが、これで満足するわけがなくて……任意のNSImageをカーソルに指定する方法について調べていたものの、なかなかうまくいかなかったので、このOS側で用意しているカーソルへの切り替えのみまとめておきました。

–> Download Xcode Project

他のアプリケーションに切り替えると通常のカーソルに戻ってしまうので、本プロジェクト側でアプリケーション切り替えのイベントハンドラでカーソルの再変更などを行うべきなのかも。

  set aImage to current application's NSImage's  imageNamed:(current application's NSImageNameComputer)
  set tmpCursor to current application's NSCursor's alloc()'s initWithImage:aImage hotSpot:{0,15}
tmpCursor's |set|()

結局、コンピュータのアイコンをマウスカーソルに指定するというところまでは持って行けた(カーソル画像の差し替えができた)わけなんですが、NSCursorの挙動を評価してみたら、カーソルが標準のものに戻るタイミングがバラバラ(他のディスプレイにカーソルが移動したとき、というわけでもない)で、挙動が謎すぎであります。

その後、対象のビュー(NSViewなど、その派生クラス)にマウスカーソルが入った/出たことを検出するイベントハンドラでマウスカーソルの形状変更を明示的に指定するような実装で落ち着きました(Edama2さんから教えていただきました。ありがとうございます)。

AppleScript名:AppDelegate.applescript
—
— AppDelegate.applescript
— CursorTest
—
— Created by Takaaki Naganoya on 2020/03/24.
— Copyright © 2020 Takaaki Naganoya. All rights reserved.
—

script AppDelegate
  property parent : class "NSObject"
  
  
— IBOutlets
  
property theWindow : missing value
  
  
on applicationWillFinishLaunching:aNotification
    — Insert code here to initialize your application before any files are opened
  end applicationWillFinishLaunching:
  
  
on applicationShouldTerminate:sender
    — Insert code here to do any housekeeping before your application quits
    
return current application’s NSTerminateNoww
  end applicationShouldTerminate:
  
  
on clicked:aSender
    set aTag to (aSender’s tag) as integer
    
if aTag = 100 then
      current application’s NSCursor’s arrowCursor()’s |set|()
    else if aTag = 101 then
      current application’s NSCursor’s disappearingItemCursor()’s |set|()
    else if aTag = 102 then
      current application’s NSCursor’s contextualMenuCursor()’s |set|()
    else if aTag = 103 then
      current application’s NSCursor’s openHandCursor()’s |set|()
    end if
  end clicked:
end script

★Click Here to Open This Script 

(Visited 56 times, 1 visits today)
Posted in AppleScript Application on Xcode System | Tagged 10.13savvy 10.14savvy 10.15savvy NSCursor NSImage | Leave a comment

指定画像をICNSに変換

Posted on 3月 19, 2020 by Takaaki Naganoya

指定画像をICNS書類に変換するAppleScriptです。

ICNS書類自体は、Classic Mac OS時代にあったアイコンの画像リソースである「icn#」リソースをファイル化したもの、と理解しています(位置付け的に、データ形式とか厳密なレベルで比較したわけではなくて)。

現在では、ICNS書類を作ってアプリケーションアイコンに指定したり、

Xcode上で解像度の異なる画像ファイルをドラッグ&ドロップすると、アプリケーションのICNSファイルを作ってくれます。

Finder上で解像度の異なる画像をフォルダ構造に入れてフォルダの拡張子をつけかえるだけでICNSと認識してくれたような記憶もあります。

そのため、ICNS書類をわざわざScriptから作る需要もないだろうと考えて掲載してこなかったのですが、意外なところでICNS書類の作成を求められました。

自作アプリケーションのカスタム書類を定義して、書類にカスタムアイコンをつけようとしたところ、PNGなどの画像では認識されず、結局ICNS書類を指定する必要に迫られました(意外)。

そんなわけで、いろいろICNS作成Scriptをまとめておきました。

こちらのScriptは実際には実行していませんが、/usr/bin/tiff2icnsコマンドがmacOS 10.15にも含まれていることを確認しています。

AppleScript名:TIFF画像をicnsに変換 v2scpt
tell application "Finder"
  set a to choose file
end tell
set theTiffPath to POSIX path of a
–128 x 128のtiff画像が必要
do shell script "/usr/bin/tiff2icns -noLarge " & (quoted form of theTiffPath)

★Click Here to Open This Script 

こちらは、オープンソースの「IcnsFactory」をフレームワーク化したIconFactory.frameworkを呼び出すバージョンです。自分が実際に使ったのはこちらです。

macOS 10.14以降ではScript Debugger上で実行するか、Script Debuggerから書き出したアプレット(Application(Enhanced))で実行するか、あるいはMacのSIPを解除して実行するなどの方法で実行できます。

Xcode上のAppleScript Applicationプロジェクトに突っ込んで呼び出せば、SIPの解除やScript Debuggerのインストールは必要ありません。

–> Download iconFactory.framework

AppleScript名:画像をICNS書類に
— Created 2017-04-14 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "IconFactory" –https://github.com/kgn/IcnsFactory

set aFile to POSIX path of (choose file)
set outFile to POSIX path of (choose file name)
set anImage to current application’s NSImage’s alloc()’s initWithContentsOfFile:aFile
set iconFam to current application’s IcnsFactory’s writeICNSToFile:outFile withImages:anImage

★Click Here to Open This Script 

(Visited 173 times, 1 visits today)
Posted in file Image | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

WebKit Utilities v2

Posted on 3月 16, 2020 by Takaaki Naganoya

AppleScriptで指定URLのページを表示する「WebKit Utilities」がmacOS 10.13以降の環境で動かなくなっていたので、書き換えて動くようにしておきました。

–> Download WebKit Utilities_archive v2

これ自体が役に立ったということはなく、単にAppleScript Librariesの書き方のサンプルと理解しています。Webサイトの表示を行うよりも1枚ものの画像やPDFにレンダリングする処理のほうがバッチ処理の中では相性がいいと思います。

また、このScriptはWkWebViewではなく古いWebViewを使っているので、じきに動かなくなります。

AppleScript名:WebKit Utilitiesで指定URLをウィンドウ表示
— Created 2017-03-24 by Takaaki Naganoya
— 2017 Piyomaru Software
use AppleScript version "2.4"
use scripting additions
use webLib : script "WebKit Utilities"

set targetURL to "http://www.piyocast.com/"
display URL targetURL window size {1024, 1024}

★Click Here to Open This Script 

AppleScript名:WebKit Utilities
— An example AppleScript/Objective-C library that uses the WebKit framework.

use AppleScript
use framework "AppKit"
use framework "WebKit"

property NSURL : a reference to current application’s NSURL
property WebView : a reference to current application’s WebView
property NSScreen : a reference to current application’s NSScreen
property NSThread : a reference to current application’s NSThread
property NSWindow : a reference to current application’s NSWindow
property NSURLRequest : a reference to current application’s NSURLRequest
property NSMutableDictionary : a reference to current application’s NSMutableDictionary

on _DisplayWebWindowWithURL:theURLString windowSize:theWindowSize
  — Create and display a horizontally centered window with a WebView
  
  
set {thisWindowWidth, thisWindowHeight} to theWindowSize
  
set screenBounds to the NSScreen’s mainScreen’s visibleFrame as any
  
  
if class of screenBounds = record then
    set screenWidth to screenBounds’s |size|’s width
    
set screenHeight to screenBounds’s |size|’s height
    
set windowLeft to ((screenWidth – thisWindowWidth) / 2) + (screenBounds’s origin’s x)
    
set windowBottom to screenHeight – thisWindowHeight + (screenBounds’s origin’s y) – 40
  else
    copy screenBounds to {{originX, originY}, {screenWidth, screenHeight}}
    
set windowLeft to ((screenWidth – thisWindowWidth) / 2) + originX
    
set windowBottom to screenHeight – thisWindowHeight + originY – 40
  end if
  
  
set theStyleMask to (get current application’s NSTitledWindowMask) + (get current application’s NSClosableWindowMask) + (get current application’s NSMiniaturizableWindowMask) + (get current application’s NSResizableWindowMask)
  
set webWindow to NSWindow’s alloc()’s initWithContentRect:(current application’s NSMakeRect(windowLeft, windowBottom, thisWindowWidth, thisWindowHeight)) ¬
    styleMask:theStyleMask backing:(current application’s NSBackingStoreBuffered) defer:false
  — set webWindow’s title to "WebView Created with AppleScript – " & theURLString
  
  
set theWebView to WebView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, thisWindowWidth, thisWindowHeight)) ¬
    frameName:"WebKit Frame" groupName:"WebKit Group"
  set webWindow’s contentView to theWebView
  
  
tell webWindow to makeKeyAndOrderFront:(missing value)
  
  
— Start loading the URL
  
  
set theURL to NSURL’s URLWithString:theURLString
  
set theURLRequest to NSURLRequest’s requestWithURL:theURL
  
tell theWebView’s mainFrame to loadRequest:theURLRequest
  
  
webWindow
end _DisplayWebWindowWithURL:windowSize:

— The following two handlers exist to deal with running on a background thread.
— If we’re on a background thread, we have to run the UI code on the main thread.

on _DisplayWebWindowMainThread:parameterDictionary
  try
    set theURLString to parameterDictionary’s objectForKey:"url string"
    
set theWindowSize to parameterDictionary’s objectForKey:"window size"
    
    
set webWindow to my _DisplayWebWindowWithURL:theURLString windowSize:theWindowSize
    
    
tell parameterDictionary to setObject:webWindow forKey:"result"
  on error errMsg number errNum
    using terms from scripting additions
      display alert "Error!" message errMsg & " (" & errNum & ")"
    end using terms from
    
tell parameterDictionary to setObject:{errMsg, errNum} forKey:"error"
  end try
end _DisplayWebWindowMainThread:

on display URL theURLString window size theWindowSize
  — All UI methods must be invoked on the main thread.
  
if (NSThread’s isMainThread) then
    my _DisplayWebWindowWithURL:theURLString windowSize:theWindowSize
  else
    — Parameters, results and error information are communicated between threads via a dictionary.
    
set parameterDictionary to NSMutableDictionary’s dictionary()
    
tell parameterDictionary to setObject:theURLString forKey:"url string"
    
tell parameterDictionary to setObject:theWindowSize forKey:"window size"
    
    
its performSelectorOnMainThread:"_DisplayWebWindowMainThread:" withObject:parameterDictionary waitUntilDone:true
    
    
— Propagate errors from the other thread
    
    
set errInfo to parameterDictionary’s objectForKey:"error"
    
if errInfo is not missing value then error errInfo’s first item number errInfo’s second item
    
    
parameterDictionary’s objectForKey:"result"
  end if
end display URL

★Click Here to Open This Script 

(Visited 113 times, 1 visits today)
Posted in GUI Internet URL | Tagged 10.13savvy 10.14savvy 10.15savvy NSMutableDictionary NSScreen NSThread NSURL NSURLRequest NSWindow WebView | Leave a comment

正方形セルの表データで指定セルに隣接するセルブロックを検出

Posted on 3月 11, 2020 by Takaaki Naganoya

正方形セルの表を形成する1次元配列上で、指定セルに隣接する指定データの入っているセルブロックを検出するAppleScriptです。

テストデータは11×11のサイズで作ってみました。本Scriptを作ることが最終目的ではないので、実戦投入はしていませんが、それなりに動いているようです。11セルの対象データを検出するのに、0.002秒ぐらい(10回実行時の平均値)。

本プログラムではセルアドレス=58のセルと隣接する「9」のデータが入っているセルのアドレスをすべて求めています。基準セルの8方向のセルアドレスを計算したうえでデータにアクセスして、「9」が入っているセルを検出。それらをまとめてすべての検出セルの8方向のアドレスを検査し、それ以上検出セル数が増加しない状態までループ処理を続けています。

本プログラムは本番プログラムを作るための習作だったので、ものすごくオーソドックスな組み方をしています。本番のプログラムでは、この「無駄に長い」処理を大幅に簡略化して3分の1ぐらいの長さになりました。

AppleScript名:findBlock2.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/10
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

property dataWidth : 11
property dataHeight : 11
property dataMax : 121

property testData : {"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "9", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "9", "9", "9", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "9", "9", "9", "9", "1", "1", "1", "1", "1", "1", ¬
  
"1", "9", "9", "9", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬
  
"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"}

set foundList to {58}

set prevFound to 1
repeat
  set foundList to findAllDirection(foundList) of me
  
set aLen to length of foundList
  
if aLen = prevFound then
    return foundList
  else
    copy aLen to prevFound
  end if
end repeat

return foundList
–> {58, 69, 68, 70, 80, 79, 81, 82, 91, 90, 92}

on findAllDirection(foundList)
  repeat with sCanCell in foundList
    
    
set nRes to findN(sCanCell) of me
    
set sRes to findS(sCanCell) of me
    
set eRes to findE(sCanCell) of me
    
set wRes to findW(sCanCell) of me
    
set nwRes to findNW(sCanCell) of me
    
set neRes to findNE(sCanCell) of me
    
set swRes to findSW(sCanCell) of me
    
set seRes to findSE(sCanCell) of me
    
    
if nRes is not equal to false then
      set newAddr to contents of (item 2 of nRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set nRes to false
      end if
    end if
    
    
if sRes is not equal to false then
      set newAddr to contents of (item 2 of sRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set sRes to false
      end if
    end if
    
    
if eRes is not equal to false then
      set newAddr to contents of (item 2 of eRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set eRes to false
      end if
    end if
    
    
if wRes is not equal to false then
      set newAddr to contents of (item 2 of wRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set wRes to false
      end if
    end if
    
    
if nwRes is not equal to false then
      set newAddr to contents of (item 2 of nwRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set nwRes to false
      end if
    end if
    
    
if neRes is not equal to false then
      set newAddr to contents of (item 2 of neRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set neRes to false
      end if
    end if
    
    
if swRes is not equal to false then
      set newAddr to contents of (item 2 of swRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set swRes to false
      end if
    end if
    
    
if seRes is not equal to false then
      set newAddr to contents of (item 2 of seRes)
      
if newAddr is not in foundList then
        set the end of foundList to newAddr
      else
        set seRes to false
      end if
    end if
    
  end repeat
  
return foundList
end findAllDirection

—————————————

on findS(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to incLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findS

on findN(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to decLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findN

on findE(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to incCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findE

on findW(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to decCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findW

on findNW(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to decLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpAddr to decCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findNW

on findNE(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to decLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpAddr to incCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findNE

on findSW(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to incLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpAddr to decCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findSW

on findSE(anAddress)
  copy anAddress to tmpAddr
  
set tmpAddr to incLine(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpAddr to incCell(tmpAddr) of me
  
if tmpAddr = false then return false
  
set tmpCon to contents of item tmpAddr of testData
  
if tmpCon = "1" then return false
  
return {true, tmpAddr}
end findSE

—————————————

on incLine(anAddress)
  if anAddress + dataWidth > dataMax then
    set anAddress to false
  else
    set anAddress to anAddress + dataWidth
  end if
  
return anAddress
end incLine

on decLine(anAddress)
  if anAddress – dataWidth < 1 then
    set anAddress to false
  else
    set anAddress to anAddress – dataWidth
  end if
  
return anAddress
end decLine

on incCell(anAddress)
  set tmpMax to anAddress div dataWidth
  
if ((anAddress + 1) div dataWidth) is not equal to tmpMax then
    set anAddress to false
  else
    if anAddress + 1 < dataMax then
      set anAddress to anAddress + 1
    else
      return false
    end if
  end if
  
return anAddress
end incCell

on decCell(anAddress)
  set tmpMax to anAddress div dataWidth
  
set tmp2Max to (anAddress – 1) div dataWidth
  
if anAddress – 1 > 0 then
    if (tmp2Max is equal to tmpMax) then
      set anAddress to anAddress – 1
    end if
  else
    set anAddress to false
  end if
  
return anAddress
end decCell

★Click Here to Open This Script 

(Visited 48 times, 1 visits today)
Posted in list | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

Numbersの表の選択範囲をシーケンシャル番号で埋める

Posted on 3月 11, 2020 by Takaaki Naganoya

Numbersの最前面の書類で選択中の表の選択範囲を1からはじまるシーケンシャル番号で埋めるAppleScriptです。

Numbers書類のセルを埋めるのは、それなりにコストの高い(処理時間が長い)処理なので、数十とか百ぐらいの要素だと、このように悠長にループで埋めても大丈夫ですが、数千とか数万セルを相手にする場合には途方もない時間がかかります。

要素数が多い場合には、CSVのファイルを組み立ててオープンする処理方法をおすすめします(一瞬で終わるので)。

この手の処理は、ほぼ「書き捨て」で保存すらしないことが多いのですが、たまたま気が向いたので保存しておきました。

本ScriptはmacOS 10.14.6/10.15.3+Numbers v6.2.1、macOS 10.13.6+Numbers v6.2で動作確認しています。

AppleScript名:Numbersの表の選択範囲をシーケンシャル番号で埋める
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/10
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

tell application "Numbers"
  tell front document
    tell active sheet
      try
        set theTable to first table whose class of selection range is range
      on error
        display notification "Numbers: There is no selection"
        
return
      end try
      
      
tell theTable
        set aRes to value of cells of selection range
      end tell
      
      
set aLen to length of aRes
      
set newList to makeSequential1DList(aLen) of me
      
      
tell theTable
        set cList to cells of selection range
      end tell
      
      
repeat with i from 1 to aLen
        set anObj to contents of item i of cList
        
set aVal to contents of item i of newList
        
        
ignoring application responses
          set value of anObj to aVal
        end ignoring
        
      end repeat
    end tell
  end tell
end tell

on makeSequential1DList(itemLen)
  set outList to {}
  
repeat with i from 1 to itemLen
    set the end of outList to i
  end repeat
  
return outList
end makeSequential1DList

★Click Here to Open This Script 

(Visited 68 times, 1 visits today)
Posted in list Number | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

mirroringの設定と解除

Posted on 3月 11, 2020 by Takaaki Naganoya

自分はディスプレイのミラーリング機能は日常的にあまり使っていません。実際にやってみたらどうだったのかをまとめてみました。

この手の処理をAppleScriptで書こうとしても、そのための命令が標準で内蔵されていないため、アプローチの方法はかぎられています。

 (1)思いっきりハードウェア寄りのプログラム(Cとかで書いた)を呼び出す
 (2)アクセシビリティ系の機能(GUI Scripting)を使ってシステム環境設定を操作する

の2つです。(2)は、画面上の要素の些細な変更によりプログラムを書き換える必要が出てくるうえに、信頼性が高くないので、あまりやりたくありません。もちろん、画面上の要素を検索しながら処理する方法もあるわけですが、それなりに(画面要素の検索に)時間がかかります。

そうなると、(1)を採用することになります。探すと………すぐにみつかりました。「mirror-displays」というコマンドラインアプリケーションです。ソースコードを読んでみると、CoreGraphics系の各種フレームワークを呼び出している、Objective-Cで書かれた(ほとんどCのコード)プログラムです。

これをスクリプトバンドルの中に入れて呼び出してみました。1回実行するとメインモニタの内容が他のモニタにミラーリングされます。もう1回実行すると、ミラーリングが解除されます。

–> Download mirroring_toggle (Script Bundle with executable command in its bundle)

mirrorコマンドのオプションには、「どのモニタをミラーリングさせるか」といった指定ができるようですが、試していないのでとくに凝った指定も何もしていません。

mirrorコマンドはmacOS 10.14でビルドして10.10以降をターゲットにしてみましたが、そこまで古い環境は手元に残っていないのでテストしていません。また、macOS 10.15のマシンには複数台のモニタをつないでいないので、macOS 10.15上でのテストも行っていません。

AppleScript名:mirroringの設定と解除
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/11
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

–https://github.com/hydra/mirror-displays
–バンドルの中に入れたmirrorコマンドをただ呼んでるだけ
set myPath to POSIX path of (path to me)
set comPath to myPath & "/Contents/Resources/mirror"
do shell script quoted form of comPath

★Click Here to Open This Script 

(Visited 301 times, 1 visits today)
Posted in shell script System | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

ServerInformationで製品情報を取得

Posted on 3月 9, 2020 by Takaaki Naganoya

AppleのPrivate Frameworkである「ServerInformation.framework」を呼び出すAppleScriptです。

AppStoreを通じて配布するアプリケーションではPrivate Frameworkの使用は問題になる可能性がありますが、ユーザーの手元で動かしているAppleScriptでPrivate Frameworkを煮ようが焼こうが関係ないと思います。

「ServerInformation.framework」は割と利用価値が高そうなものであります。実際にGithub上で探したサンプルをAppleScriptに翻訳して試してみました。

本サンプルは、/System/Library/PrivateFrameworks/という、ふだんFrameworkを呼び出す先「ではない」ディレクトリに入っているFrameworkを呼び出すサンプルでもあり、NSBundleを通じてFrameworkを呼び出す実例でもあります。

この方法を利用すれば、最新のmacOSで(SIPを解除しないで)そのままでは呼び出せなくなっていたホームディレクトリ下のFrameworkとかアプレット内に同梱したFrameworkをローディングして呼び出すことができそうな雰囲気があります。

AppleScript名:ServerInformationで製品情報を取得.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/09
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
— https://gist.github.com/erikng/d90d21f502351d64a541600226626a28

use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

set ServerInformation to current application’s NSBundle’s bundleWithPath:"/System/Library/PrivateFrameworks/ServerInformation.framework"
set ServerCompatibility to current application’s NSBundle’s bundleWithPath:"/System/Library/PrivateFrameworks/ServerCompatibility.framework"

set ServerInformationComputerModelInfo to ServerInformation’s classNamed:"ServerInformationComputerModelInfo"
set SVCSystemInfo to ServerCompatibility’s classNamed:"SVCSystemInfo"

set myInfo to SVCSystemInfo’s currentSystemInfo()

set exInfo to (ServerInformationComputerModelInfo’s attributesForModelIdentifier:(myInfo’s computerModelIdentifier())) as record

set anArchitecture to exInfo’s architecture
–> "x86_64"

set aMonoImageSel to exInfo’s monochromeSelectedHardwareImage
–> NSImage (Gray)

set aMonoImage to exInfo’s monochromeHardwareImage
–> NSImage (Gray)

set aDesc to exInfo’s |description|
–> "15インチMacBook Pro Retinaディスプレイを装備、デュアルコアIntel Core i7プロセッサ搭載(アルミニウムユニボディ)、2012年の中期に投入。"
–> "Mac mini Intelデュアルコアプロセッサおよび統合型グラフィックス搭載、2014年後期に投入。"
–> "MacBook Air 11インチディスプレイを装備、2011年の中期に投入。"

set aModel to exInfo’s model
–> "MacBook Pro"
–> "Mac mini"
–> "MacBook Air"

set aProcessor to exInfo’s processor
–> "Intel Core i7"
–> "デュアルコアIntel Core i5、デュアルコアIntel Core i7"
–> "Dual-Core Intel Core i5、Intel Core i7"

set aMarketModel to exInfo’s marketingModel
–> "15インチMacBook Pro, Retinaディスプレイ, Intel Core i7 (Mid 2012)"
–> "Mac mini(Late 2014)"
–> "11インチMacBook Air(Mid 2011)"

set aColorImage to exInfo’s hardwareImage
–> NSImage (Color)

★Click Here to Open This Script 

(Visited 27 times, 1 visits today)
Posted in System | Tagged 10.14savvy 10.15savvy | Leave a comment

使用中のMacの製品呼称を取得する v4

Posted on 3月 8, 2020 by Takaaki Naganoya

使用中のMacの製品呼称を取得するAppleScriptです。

ながらく、この手のルーチンを使い続けてきましたが、macOS 10.15でエラーが出るようになりました。

理由を確認してみたところ、パス名の一部がmacOS 10.15で変更になっていることがわかりました。

目下、Xcode上でアプリケーションを作成すると、ローカライズしたリソースのフォルダについては、「English.lproj」ではなく「en.lproj」と、言語コードが用いられるようになってきました。この、「English」と「en」の変更がOS内部のコンポーネントについても行われた「だけ」というのが理由のようです。

ちなみに、パス名を無意味に途中で切ってつなげているのは、Blog(HTML)やMarkDownのドキュメントに入れたときに、折り返しされずにレンダリング品質を下げる原因になる(行がそこだけ伸びるとか、ページ全体の文字サイズが強制的に小さくなるとか)ためです。

AppleScript名:使用中のMacの製品呼称を取得する v4.scptd
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/08
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—
use AppleScript version "2.4" — Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set myInfo to retModelInfo() of me
–> "Mac mini (Late 2014)"

on retModelInfo()
  set v2 to system attribute "sys2"
  
— macOS 10.15.3 –> 15
  
  
if v2 < 15 then
    –macOS 10.14まで
    
set pListPath to "/System/Library/PrivateFrameworks/ServerInformation.framework/" & "Versions/A/Resources/English.lproj/SIMachineAttributes.plist"
  else
    –macOS 10.15以降
    
set pListPath to "/System/Library/PrivateFrameworks/ServerInformation.framework/" & "Versions/A/Resources/en.lproj/SIMachineAttributes.plist"
  end if
  
  
set aRec to retDictFromPlist(pListPath) of me
  
set hwName to (do shell script "sysctl -n hw.model")
  
–>  "Macmini7,1"
  
  
set aMachineRec to retRecordByLabel(aRec, hwName) of me
  
  
set aMachineRec2 to contents of first item of aMachineRec
  
return (marketingModel of _LOCALIZABLE_ of aMachineRec2)
end retModelInfo

on retDictFromPlist(aPath)
  set thePath to current application’s NSString’s stringWithString:aPath
  
set thePath to thePath’s stringByExpandingTildeInPath()
  
set theDict to current application’s NSDictionary’s dictionaryWithContentsOfFile:thePath
  
return theDict as record
end retDictFromPlist

on retRecordByLabel(aRec as record, aKey as string)
  set aDic to current application’s NSDictionary’s dictionaryWithDictionary:aRec
  
set aVal to aDic’s valueForKey:aKey
  
return aVal as list
end retRecordByLabel

on retRecordByKeyPath(aRec as record, aKey as string)
  set aDic to current application’s NSDictionary’s dictionaryWithDictionary:aRec
  
set aVal to aDic’s valueForKeyPath:aKey
  
return aVal
end retRecordByKeyPath

★Click Here to Open This Script 

(Visited 37 times, 1 visits today)
Posted in shell script System | Tagged 10.15savvy NSDictionary NSString | Leave a comment

マウス充電用AppleScript

Posted on 3月 6, 2020 by Takaaki Naganoya

本Scriptはいつも書き捨てにするAppleScriptですが、使用頻度はそれなりに高いものです。

AppleのMagic Mouse 2を充電するには、裏返してLightningケーブルを挿す必要があります。

STEP1:コンピュータをスリープさせる
STEP2:マウスを裏返す
STEP3:ケーブルを挿して充電する

という手順になるわけですが、、、マウスを裏返した時点でボタンが押されたりして、充電できないケースが多々あります。

そこで、本Scriptをスクリプトエディタ上で実行して、10秒以内にマウスに充電ケーブルを挿すと、あとからコンピュータがスリープ。問題なくマウスを充電できます。

AppleScript名:マウス充電用Script
delay 10

tell application "System Events" to sleep

★Click Here to Open This Script 

(Visited 65 times, 1 visits today)
Posted in How To System | Tagged 10.13savvy 10.14savvy 10.15savvy System Events | Leave a comment

FileMaker v18でAppleScriptを使えるように設定

Posted on 3月 6, 2020 by Takaaki Naganoya

Classic MacOS時代はJeditとFileMaker Proがないと機能がなさすぎて即死でしたが、現在はAppleScriptのソリューションを成立させるのにFileMakerが必須ということもなくなりました。本Blog掲載のサンプルを見ていただければ分かるように、データのソーティングも抽出も、AppleScriptだけで相当なことがこなせます。

AppleScript単体でもCocoaの機能を利用することで、数万〜数十万件レベルのデータ件数であれば、別にFileMakerデータベースを併用する必要もなくなってきました。

ただ、かといってFileMakerの魅力が減ったわけではありません。とくに、小規模なチームで短期間で業務支援システムを組み立てる必要がある場合など、FileMakerの手軽さは圧倒的です(個人事業者ならなおのことです)。さらに、各種データソースからデータを自動で取り込んで蓄積する部品として、FileMakerが使えることは大きな力になります。

FileMakerは昔とはやや位置付けが変わりましたが、それでも大きな価値を持っています。

FileMakerのデータベースがAppleScriptから使えるようになるまで

実際にFileMaker v18のお試し版(FileMaker Advanced)をダウンロードして、AppleScriptを利用できるように設定を行ってみました。

デフォルトで、FileMakerのアプリケーションにnameやversionなどを問い合わせすることは可能ですが、データベースへのアクセスは行えません。FileMakerのアプリケーション本体にAppleScript制御受付の設定があるわけではなく、データベース書類に対してユーザー権限とDB書類オープン時のユーザー設定などを行うことで、AppleScriptからアクセスできるようになります。

データベースに対して権限設定を行うので、まずは対象となるデータベースをオープンしておく必要があります。そのうえで、「ファイル」>「管理」>「セキュリティ」を実行。

新規アカウント「AS User」(なんでもいい)を作成し、

この新規作成したアカウント「AS User」の権限を新規に定義します(新規アクセス権セット)。

拡張アクセス件で、必要な権限を設定した上で「Apple EventおよびActiveXによるFileMaker操作の実行を許可(fmextscriptacess)」にチェックを入れておきます。

ユーザーおよびユーザー権限を設定した上で、データベース書類に対して、この新規作成したアカウント「AS User」でオープンするように設定を行います。「ファイル」>「ファイルオプション…」を実行して、

「ファイルオプション」ダイアログ中の「開く」タブで、「次のアカウントを使用してログイン」の欄にユーザー名「AS User」と設定したパスワードを設定して「OK」ボタンをクリック。

これで、いったんデータベース書類をクローズして再度オープンし直すと、ユーザー名「AS User」でオープンした状態になり、AppleScriptからの操作を受け付けるようになります。

昔のFileMakerではpropertyを求めることでファイルメーカーDBのスキーマ定義やレイアウト一覧などが、パスワードを設定してある状態ですらすべて取得できていましたが(いろいろリバースエンジニアリングしました)、現在のFileMakerではproperty属性によるアクセスが行えないので、そこまでガバガバではないようです。

(Visited 418 times, 3 visits today)
Posted in How To | Tagged 10.14savvy 10.15savvy FileMaker | Leave a comment

common elements Libの評価アプリケーションを配布

Posted on 3月 5, 2020 by Takaaki Naganoya

ライブラリのインストール方法やらスクリプトエディタの使い方やらがわかっていないとcommon elements Libを実際に使って試すことができないので、実際に機能を評価できるよう最低限のGUIをつけてみました。

–> Download GUI App Executable(Zip archive, 57KB)

macOS 10.13,10.14, 10.15上で動作します。実行にはインターネット接続を必要とします。

(Visited 33 times, 1 visits today)
Posted in AppleScript Application on Xcode Script Libraries | Tagged 10.13savvy 10.14savvy 10.15savvy | Leave a comment

common elements Libをロシア語などのクエリーで呼び出す

Posted on 3月 3, 2020 by Takaaki Naganoya

WikipediaのREST APIを呼び出して、2つの単語の共通項を計算する「common elements Lib」を作って実際にいろいろ評価していますが、ロシア語を指定したときに結果が得られないという現象に直面していました。

ロシア語を記述するキリル文字のエンコーディング指定がよくなかったのか、Wikipediaのロシア語サーバーの問題なのか、どこに問題点があるのかよくわかっていませんでした(そういう問題のあぶり出しのためにリリースしてみた事情があります)。

とりあえず人名をGoogle翻訳でロシア語+キリル文字に翻訳してロシア語Wikipediaに突っ込んでみても結果が得られず首をひねっていましたが、ロシア語の人名表記が、

First name Family name

ではなく、

Family name, First name

のフォーマットであることに気づきました。この語順で人名を突っ込んでみたところ、無事結果が得られることを確認しました。

AppleScript名:sample_russian
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/03
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

use comLib : script "common elements Lib"

–"Family Name, First Name" in Russian Language

–"George Lucas" and "Steven Spielberg"
set cRes to list up common elements with {"Лукас, Джордж", "Спилберг, Стивен"} with language "ru"
–> {"Награда имени Ирвинга Тальберга", "Индиана Джонс", "Кинофантастика", "Золотой глобус", "Монтажёр", "Industrial Light & Magic", "Форд, Харрисон", "DreamWorks", "Премия «Сатурн» за лучший сценарий", "Сиквел", "Продюсер", "Кинорежиссёр", "Калифорния", "Сценарист", "Премия «Сатурн» за лучшую режиссуру", "Оскар (кинопремия)"}

–"Larry Tesler" and "Steve Jobs"
set dRes to list up common elements with {"Теслер, Ларри ", "Джобс, Стив"} with language "ru"
–> {"Apple Computer", "Xerox PARC", "Smalltalk", "Стэнфордский университет"}

★Click Here to Open This Script 

ウクライナ語の人名は、

First name Family name

となっているので、そのように書けば結果が得られます。登録記事数がそれほど多くないので、かなり検索語句を選ぶ印象ではあります。

AppleScript名:sample_Ukrainian
–Українська (Ukrainian)
use comLib : script "common elements Lib"

–"Bill Gates" and "Steve Jobs"
set dRes to list up common elements with {"Білл Гейтс", "Стів Джобс"} with language "uk"
–> {"США", "IBM", "Долар США", "Майкрософт", "Головний виконавчий директор", "Стенфордський університет", "Персональний комп’ютер"}

★Click Here to Open This Script 

(Visited 55 times, 1 visits today)
Posted in Natural Language Processing REST API Script Libraries | Tagged 10.10savvy 10.12savvy 10.13savvy 10.14savvy 10.15savvy | 1 Comment

指定文字列ではじまるURLをオープン中のTabをクローズ

Posted on 3月 1, 2020 by Takaaki Naganoya

Safariでオープン中のウィンドウ/Tabのうち、指定URLではじまるもの(この場合にはGoogle翻訳)をオープン中のものだけをクローズする掃除用のAppleScriptです。

TabのIDを取得して、1から処理するとナンバリングがおかしくなるので、後ろから処理しているあたりが「ワザ」とでもいうべきものでしょうか。

AppleScript名:指定文字列ではじまるURLをオープン中のTabをクローズ
—
–  Created by: Takaaki Naganoya
–  Created on: 2020/03/01
—
–  Copyright © 2020 Piyomaru Software, All Rights Reserved
—

set targURL to "https://translate.google.co.jp" –Google翻訳
closeSafariTabsBeginsWithAURL(targURL) of me

on closeSafariTabsBeginsWithAURL(targURL)
  tell application "Safari"
    set wCount to (every window whose visible is true)
    
    
repeat with w in wCount
      set aWin to contents of w
      
      
tell aWin
        set tabCount to count every tab
        
repeat with t from tabCount to 1 by -1
          tell tab t
            set aURL to URL of it
            
if aURL begins with targURL then
              close
            end if
          end tell
        end repeat
      end tell
      
    end repeat
  end tell
end closeSafariTabsBeginsWithAURL

★Click Here to Open This Script 

(Visited 63 times, 1 visits today)
Posted in URL | Tagged 10.13savvy 10.14savvy 10.15savvy Safari | Leave a comment

電子書籍(PDF)をオンラインストアで販売中!

Google Search

Popular posts

  • AppleScriptによるWebブラウザ自動操縦ガイド
  • macOS 13, Ventura(継続更新)
  • ドラッグ&ドロップ機能の未来?
  • macOS 12.x上のAppleScriptのトラブルまとめ
  • PFiddlesoft UI Browserが製品終了に
  • macOS 12.3 beta 5、ASの障害が解消される(?)
  • SF Symbolsを名称で指定してPNG画像化
  • 新刊発売:AppleScriptによるWebブラウザ自動操縦ガイド
  • macOS 12.3 beta4、まだ直らないASまわりの障害
  • macOS 12.3上でFinder上で選択中のファイルをそのままオープンできない件
  • Safariで表示中のYouTubeムービーのサムネイル画像を取得
  • macOS 12のスクリプトエディタで、Context Menu機能にバグ
  • Pixelmator Pro v2.4.1で新機能追加+AppleScriptコマンド追加
  • 人類史上初、魔導書の観点から書かれたAppleScript入門書「7つの宝珠」シリーズ開始?!
  • CotEditor v4.1.2でAppleScript系の機能を追加
  • macOS 12.5(21G72)がリリースされた!
  • UI Browserがgithub上でソース公開され、オープンソースに
  • Pages v12に謎のバグ。書類上に11枚しか画像を配置できない→解決
  • 新発売:AppleScriptからSiriを呼び出そう!
  • iWork 12.2がリリースされた

Tags

10.11savvy (1102) 10.12savvy (1243) 10.13savvy (1391) 10.14savvy (586) 10.15savvy (434) 11.0savvy (274) 12.0savvy (174) 13.0savvy (34) CotEditor (60) Finder (47) iTunes (19) Keynote (97) NSAlert (60) NSArray (51) NSBezierPath (18) NSBitmapImageRep (21) NSBundle (20) NSButton (34) NSColor (51) NSDictionary (27) NSFileManager (23) NSFont (18) NSImage (42) NSJSONSerialization (21) NSMutableArray (62) NSMutableDictionary (21) NSPredicate (36) NSRunningApplication (56) NSScreen (30) NSScrollView (22) NSString (118) NSURL (97) NSURLRequest (23) NSUTF8StringEncoding (30) NSUUID (18) NSView (33) NSWorkspace (20) Numbers (55) Pages (36) Safari (41) Script Editor (20) WKUserContentController (21) WKUserScript (20) WKWebView (23) WKWebViewConfiguration (22)

カテゴリー

  • 2D Bin Packing
  • 3D
  • AirDrop
  • AirPlay
  • Animation
  • AppleScript Application on Xcode
  • beta
  • Bluetooth
  • Books
  • boolean
  • bounds
  • Bug
  • Calendar
  • call by reference
  • Clipboard
  • Code Sign
  • Color
  • Custom Class
  • dialog
  • drive
  • exif
  • file
  • File path
  • filter
  • folder
  • Font
  • Font
  • GAME
  • geolocation
  • GUI
  • GUI Scripting
  • Hex
  • History
  • How To
  • iCloud
  • Icon
  • Image
  • Input Method
  • Internet
  • iOS App
  • JavaScript
  • JSON
  • JXA
  • Keychain
  • Keychain
  • Language
  • Library
  • list
  • Locale
  • Machine Learning
  • Map
  • Markdown
  • Menu
  • Metadata
  • MIDI
  • MIME
  • Natural Language Processing
  • Network
  • news
  • Noification
  • Notarization
  • Number
  • Object control
  • OCR
  • OSA
  • PDF
  • Peripheral
  • PRODUCTS
  • QR Code
  • Raw AppleEvent Code
  • Record
  • recursive call
  • regexp
  • Release
  • Remote Control
  • Require Control-Command-R to run
  • REST API
  • Review
  • RTF
  • Sandbox
  • Screen Saver
  • Script Libraries
  • sdef
  • search
  • Security
  • selection
  • shell script
  • Shortcuts Workflow
  • Sort
  • Sound
  • Spellchecker
  • Spotlight
  • SVG
  • System
  • Tag
  • Telephony
  • Text
  • Text to Speech
  • timezone
  • Tools
  • Update
  • URL
  • UTI
  • Web Contents Control
  • WiFi
  • XML
  • XML-RPC
  • イベント(Event)
  • 未分類

アーカイブ

  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月
  • 2022年11月
  • 2022年10月
  • 2022年9月
  • 2022年8月
  • 2022年7月
  • 2022年6月
  • 2022年5月
  • 2022年4月
  • 2022年3月
  • 2022年2月
  • 2022年1月
  • 2021年12月
  • 2021年11月
  • 2021年10月
  • 2021年9月
  • 2021年8月
  • 2021年7月
  • 2021年6月
  • 2021年5月
  • 2021年4月
  • 2021年3月
  • 2021年2月
  • 2021年1月
  • 2020年12月
  • 2020年11月
  • 2020年10月
  • 2020年9月
  • 2020年8月
  • 2020年7月
  • 2020年6月
  • 2020年5月
  • 2020年4月
  • 2020年3月
  • 2020年2月
  • 2020年1月
  • 2019年12月
  • 2019年11月
  • 2019年10月
  • 2019年9月
  • 2019年8月
  • 2019年7月
  • 2019年6月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2019年1月
  • 2018年12月
  • 2018年11月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年7月
  • 2018年6月
  • 2018年5月
  • 2018年4月
  • 2018年3月
  • 2018年2月

https://piyomarusoft.booth.pm/items/301502

メタ情報

  • 登録
  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org

Forum Posts

  • 人気のトピック
  • 返信がないトピック

メタ情報

  • 登録
  • ログイン
  • 投稿フィード
  • コメントフィード
  • WordPress.org
Proudly powered by WordPress
Theme: Flint by Star Verte LLC