| 001 | #!/usr/bin/env osascript |
| 002 | #coding: utf-8 |
| 003 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7 |
| 004 | (* |
| 005 |
|
| 006 | ユーザーの ~/Library/Application Support/bin にインストールする |
| 007 |
|
| 008 | githubのRSSから対象のバイナリーをダウンロード展開する |
| 009 | 7zz インストール |
| 010 |
|
| 011 | v2 20250422 XMLとHTMLで処理をわけた |
| 012 |
|
| 013 | com.cocolog-nifty.quicktimer.icefloe *) |
| 014 | ----+----1----+----2----+-----3----+----4----+----5----+----6----+----7 |
| 015 | use AppleScript version "2.8" |
| 016 | use framework "Foundation" |
| 017 | use framework "AppKit" |
| 018 | use framework "UniformTypeIdentifiers" |
| 019 | use scripting additions |
| 020 | property refMe : a reference to current application |
| 021 |
|
| 022 |
|
| 023 | ################### |
| 024 | #【設定項目1】展開(解凍)先 |
| 025 | #インストール場所はお好みで |
| 026 | # set str7zPath to ("~/bin/7zip/7zz") as text |
| 027 | set str7zPath to ("~/Library/Application Support/bin/7zip/7zz") as text |
| 028 |
|
| 029 | ################### |
| 030 | #【設定項目2】GitHubURL |
| 031 | set strRepositoryURL to ("https://github.com/ip7z/7zip") as text |
| 032 |
|
| 033 |
|
| 034 | ################### |
| 035 | #なければインストール |
| 036 | set ocid7zPathStr to refMe's NSString's stringWithString:(str7zPath) |
| 037 | set ocid7zPath to ocid7zPathStr's stringByStandardizingPath() |
| 038 | set ocid7zPathURL to refMe's NSURL's alloc()'s initFileURLWithPath:(ocid7zPath) isDirectory:(false) |
| 039 | set appFileManager to refMe's NSFileManager's defaultManager() |
| 040 | set boolDirExists to appFileManager's fileExistsAtPath:(ocid7zPath) isDirectory:(true) |
| 041 | if boolDirExists is true then |
| 042 | log "インストール済み" |
| 043 | else |
| 044 | log "インストールします" |
| 045 | end if |
| 046 |
|
| 047 | ########################## |
| 048 | # インストール先フォルダを確保 |
| 049 | set ocidBinDirPathURL to ocid7zPathURL's URLByDeletingLastPathComponent() |
| 050 | set strBinDirPath to ocidBinDirPathURL's |path|() as text |
| 051 | #BinDirインストール先 |
| 052 | set ocidAttrDict to refMe's NSMutableDictionary's alloc()'s init() |
| 053 | ocidAttrDict's setValue:(448) forKey:(refMe's NSFilePosixPermissions) |
| 054 | set listDone to appFileManager's createDirectoryAtURL:(ocidBinDirPathURL) withIntermediateDirectories:(true) attributes:(ocidAttrDict) |error|:(reference) |
| 055 |
|
| 056 | ########################## |
| 057 | # GitHub RSSのURL |
| 058 | set strRssURL to ("" & strRepositoryURL & "/tags.atom") as text |
| 059 | set ocidURLString to refMe's NSString's stringWithString:(strRssURL) |
| 060 | set ocidRssURL to refMe's NSURL's alloc()'s initWithString:(ocidURLString) |
| 061 | log ocidRssURL's absoluteString() as text |
| 062 |
|
| 063 | ########################## |
| 064 | #XML取得 |
| 065 | set ocidReadXML to doGetRootElementXML(ocidRssURL) |
| 066 | if ocidReadXML is false then |
| 067 | return "XMLの取得に失敗しました" |
| 068 | end if |
| 069 |
|
| 070 |
|
| 071 | ########################## |
| 072 | #バージョン取得 linkのURLを使う |
| 073 | set ocidRootElement to ocidReadXML's rootElement() |
| 074 | #リンクの最初の項目が最新 |
| 075 | set listResponse to (ocidRootElement's nodesForXPath:("//entry/link/@href") |error|:(reference)) |
| 076 | set ocidLinkElementArray to (item 1 of listResponse) |
| 077 | #▼▼▼▼【要カスタマイズ】Arrayの何コ目が対象か? |
| 078 | set ocidFirstElement to ocidLinkElementArray's objectAtIndex:(0) |
| 079 | set ocidFirstElement to ocidFirstElement's stringValue() |
| 080 | #リリースページのURL |
| 081 | set ocidLinkURL to refMe's NSURL's alloc()'s initWithString:(ocidFirstElement) |
| 082 | log ocidLinkURL's absoluteString() as text |
| 083 | #ラストパス=バージョン |
| 084 | set ocidVerNo to ocidLinkURL's lastPathComponent() |
| 085 | #【要customize】ここはアプリケーションによってカスタマイズが必要 |
| 086 | set ocidVerNo to (ocidVerNo's stringByReplacingOccurrencesOfString:("v") withString:("")) |
| 087 | #カンマ有りのバージョン番号 |
| 088 | set strVerNo to ocidVerNo as text |
| 089 | #カンマ無しのバージョン番号 |
| 090 | set ocidVerNoStr to (ocidVerNo's stringByReplacingOccurrencesOfString:(".") withString:("")) |
| 091 | set strVerNoStr to ocidVerNoStr as text |
| 092 |
|
| 093 | ########################## |
| 094 | #リリースアセットのHTMLパーツ部分 |
| 095 | set strAssetsURL to ("" & strRepositoryURL & "/releases/expanded_assets/" & strVerNo & "") as text |
| 096 | set ocidAssetsURL to (refMe's NSURL's alloc()'s initWithString:(strAssetsURL)) |
| 097 | log ocidAssetsURL's absoluteString() as text |
| 098 |
|
| 099 | ########################## |
| 100 | #HTML取得 |
| 101 | set ocidReadXML to doGetRootElementHTML(ocidAssetsURL) |
| 102 |
|
| 103 | ########################## |
| 104 | #バージョン取得 linkのURLを使う |
| 105 | set ocidRootElement to ocidReadXML's rootElement() |
| 106 | # log ocidRootElement's XMLString() as text |
| 107 | #リンクの最初の項目が最新 |
| 108 | set listResponse to (ocidRootElement's nodesForXPath:("//div/ul/li/div/a/@href") |error|:(reference)) |
| 109 | set ocidReleaseNodeArray to (item 1 of listResponse) |
| 110 | #▼▼▼▼【要カスタマイズ】 アセットの何番目が対象か? |
| 111 | set ocidReleaseNode to ocidReleaseNodeArray's objectAtIndex:(7) |
| 112 | set ocidReleasePath to ocidReleaseNode's stringValue() |
| 113 |
|
| 114 | #URLコンポーネント初期化 |
| 115 | set ocidURLComponents to refMe's NSURLComponents's alloc()'s init() |
| 116 | ###スキーム を追加 |
| 117 | ocidURLComponents's setScheme:("https") |
| 118 | ###ホストを追加 |
| 119 | ocidURLComponents's setHost:("github.com") |
| 120 | ###パスを追加 |
| 121 | ocidURLComponents's setPath:(ocidReleasePath) |
| 122 | ##URLに戻して テキストにしておく |
| 123 | set ocidReleaseURL to ocidURLComponents's |URL|() |
| 124 | log ocidReleaseURL's absoluteString() as text |
| 125 | # |
| 126 | set ocidReleaseFileName to ocidReleaseURL's lastPathComponent() |
| 127 |
|
| 128 |
|
| 129 | ########################## |
| 130 | #保存先テンポラリーディレクトリ |
| 131 | set ocidTempDirURL to appFileManager's temporaryDirectory() |
| 132 | set ocidUUID to refMe's NSUUID's alloc()'s init() |
| 133 | set ocidUUIDString to ocidUUID's UUIDString |
| 134 | set ocidSaveDirPathURL to ocidTempDirURL's URLByAppendingPathComponent:(ocidUUIDString) isDirectory:(true) |
| 135 |
|
| 136 | #フォルダ作成 |
| 137 | set ocidAttrDict to refMe's NSMutableDictionary's alloc()'s init() |
| 138 | ocidAttrDict's setValue:(511) forKey:(refMe's NSFilePosixPermissions) |
| 139 | set listDone to appFileManager's createDirectoryAtURL:(ocidSaveDirPathURL) withIntermediateDirectories:(true) attributes:(ocidAttrDict) |error|:(reference) |
| 140 |
|
| 141 | ###パス |
| 142 | set ocidDownloadFilePathURL to ocidSaveDirPathURL's URLByAppendingPathComponent:(ocidReleaseFileName) isDirectory:(false) |
| 143 | set strDownloadFilePath to ocidDownloadFilePathURL's |path|() as text |
| 144 |
|
| 145 | log "ダウンロード開始" |
| 146 | ########################## |
| 147 | #NSDATA |
| 148 | set ocidOption to (refMe's NSDataReadingMappedIfSafe) |
| 149 | set listResponse to refMe's NSData's alloc()'s initWithContentsOfURL:(ocidReleaseURL) options:(ocidOption) |error|:(reference) |
| 150 | if (item 2 of listResponse) = (missing value) then |
| 151 | log "initWithContentsOfURL 正常処理" |
| 152 | set ocidReadData to (item 1 of listResponse) |
| 153 | else if (item 2 of listResponse) ≠ (missing value) then |
| 154 | set strErrorNO to (item 2 of listResponse)'s code() as text |
| 155 | set strErrorMes to (item 2 of listResponse)'s localizedDescription() as text |
| 156 | refMe's NSLog("■:" & strErrorNO & strErrorMes) |
| 157 | return "initWithContentsOfURL エラーしました" & strErrorNO & strErrorMes |
| 158 | end if |
| 159 |
|
| 160 | ##NSDATA |
| 161 | set ocidOption to (refMe's NSDataWritingAtomic) |
| 162 | set listDone to ocidReadData's writeToURL:(ocidDownloadFilePathURL) options:(ocidOption) |error|:(reference) |
| 163 | if (item 1 of listDone) is true then |
| 164 | log "writeToURL ダウンロード正常処理" |
| 165 | else if (item 2 of listDone) ≠ (missing value) then |
| 166 | set strErrorNO to (item 2 of listDone)'s code() as text |
| 167 | set strErrorMes to (item 2 of listDone)'s localizedDescription() as text |
| 168 | refMe's NSLog("■:" & strErrorNO & strErrorMes) |
| 169 | return "writeToURL エラーしました" & strErrorNO & strErrorMes |
| 170 | end if |
| 171 |
|
| 172 | ########################## |
| 173 | #▼▼▼▼【要カスタマイズ】 |
| 174 | #提供ファイル形式によってカスタマイズ |
| 175 | set strCommandText to ("/usr/bin/bsdtar -xJf \"" & strDownloadFilePath & "\" -C \"" & strBinDirPath & "\"") |
| 176 | log doZshShellScript(strCommandText) |
| 177 |
|
| 178 | ########################## |
| 179 | #拡張属性Extended Attributes (EA)削除 |
| 180 | set strCommandText to ("/usr/bin/xattr -cr \"" & strBinDirPath & "\"") |
| 181 | log doZshShellScript(strCommandText) |
| 182 |
|
| 183 | ########################## |
| 184 | #インストール先を開く |
| 185 | set appSharedWorkspace to refMe's NSWorkspace's sharedWorkspace() |
| 186 | set boolDone to appSharedWorkspace's openURL:(ocidBinDirPathURL) |
| 187 |
|
| 188 | return |
| 189 |
|
| 190 | ########################## |
| 191 | # 【通常】ZSH 実行 |
| 192 | to doZshShellScript(argCommandText) |
| 193 | set strCommandText to argCommandText as text |
| 194 | log return & strCommandText & return |
| 195 | set strExec to ("/bin/zsh -c '" & strCommandText & "'") as text |
| 196 | log return & strExec & return |
| 197 | ########## |
| 198 | #コマンド実行 |
| 199 | try |
| 200 | log "コマンド開始" |
| 201 | set strResnponse to (do shell script strExec) as text |
| 202 | log "コマンド終了" |
| 203 | on error |
| 204 | return false |
| 205 | end try |
| 206 | return true |
| 207 | end doZshShellScript |
| 208 |
|
| 209 |
|
| 210 |
|
| 211 | ########################## |
| 212 | #XML取得 |
| 213 | to doGetRootElementXML(argURL) |
| 214 | ########################## |
| 215 | #NSDATA |
| 216 | set ocidOption to (refMe's NSXMLNodePreserveAll) + (refMe's NSDataReadingMappedIfSafe) |
| 217 | set listResponse to refMe's NSData's alloc()'s initWithContentsOfURL:(argURL) options:(ocidOption) |error|:(reference) |
| 218 | if (item 2 of listResponse) = (missing value) then |
| 219 | # log "initWithContentsOfURL 正常処理" |
| 220 | set ocidReadData to (item 1 of listResponse) |
| 221 | else if (item 2 of listResponse) ≠ (missing value) then |
| 222 | set strErrorNO to (item 2 of listResponse)'s code() as text |
| 223 | set strErrorMes to (item 2 of listResponse)'s localizedDescription() as text |
| 224 | refMe's NSLog("■:" & strErrorNO & strErrorMes) |
| 225 | log "initWithContentsOfURL エラーしました" & strErrorNO & strErrorMes |
| 226 | return false |
| 227 | end if |
| 228 | ########################## |
| 229 | #NSXML |
| 230 | set ocidOption to (refMe's NSXMLDocumentTidyXML) |
| 231 | set listResponse to refMe's NSXMLDocument's alloc()'s initWithData:(ocidReadData) options:(ocidOption) |error|:(reference) |
| 232 | if (item 2 of listResponse) = (missing value) then |
| 233 | # log "initWithData 正常処理" |
| 234 | set ocidReadXML to (item 1 of listResponse) |
| 235 | else if (item 2 of listResponse) ≠ (missing value) then |
| 236 | set strErrorNO to (item 2 of listResponse)'s code() as text |
| 237 | set strErrorMes to (item 2 of listResponse)'s localizedDescription() as text |
| 238 | refMe's NSLog("■:" & strErrorNO & strErrorMes) |
| 239 | log "initWithData エラーしました" & strErrorNO & strErrorMes |
| 240 | end if |
| 241 | return ocidReadXML |
| 242 | end doGetRootElementXML |
| 243 |
|
| 244 |
|
| 245 |
|
| 246 | ########################## |
| 247 | #HTML取得 |
| 248 | to doGetRootElementHTML(argURL) |
| 249 | ########################## |
| 250 | #NSDATA |
| 251 | set ocidOption to (refMe's NSDataReadingMappedIfSafe) |
| 252 | set listResponse to refMe's NSData's alloc()'s initWithContentsOfURL:(argURL) options:(ocidOption) |error|:(reference) |
| 253 | if (item 2 of listResponse) = (missing value) then |
| 254 | log "initWithContentsOfURL 正常処理" |
| 255 | set ocidReadData to (item 1 of listResponse) |
| 256 | else if (item 2 of listResponse) ≠ (missing value) then |
| 257 | set strErrorNO to (item 2 of listResponse)'s code() as text |
| 258 | set strErrorMes to (item 2 of listResponse)'s localizedDescription() as text |
| 259 | refMe's NSLog("■:" & strErrorNO & strErrorMes) |
| 260 | log "initWithContentsOfURL エラーしました" & strErrorNO & strErrorMes |
| 261 | return false |
| 262 | end if |
| 263 | ########################## |
| 264 | #NSXML |
| 265 | set ocidOption to (refMe's NSXMLNodePreserveAll) + (refMe's NSXMLDocumentTidyHTML) |
| 266 | set listResponse to refMe's NSXMLDocument's alloc()'s initWithData:(ocidReadData) options:(ocidOption) |error|:(reference) |
| 267 | if (item 2 of listResponse) = (missing value) then |
| 268 | log "initWithData 正常処理" |
| 269 | set ocidReadHTML to (item 1 of listResponse) |
| 270 | else if (item 2 of listResponse) ≠ (missing value) then |
| 271 | set ocidReadHTML to (item 1 of listResponse) |
| 272 | #HTMLの場合エラーのログは出すけどエラーで終了にはしない |
| 273 | set strErrorNO to (item 2 of listResponse)'s code() as text |
| 274 | set strErrorMes to (item 2 of listResponse)'s localizedDescription() as text |
| 275 | refMe's NSLog("■:" & strErrorNO & strErrorMes) |
| 276 | log "initWithData エラーしました" & strErrorNO & strErrorMes |
| 277 | end if |
| 278 | return ocidReadHTML |
| 279 | end doGetRootElementHTML |