Archive for the 'NSRegularExpression' Category

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