Safariの閲覧履歴のdatabaseにアクセスして、domain単位でベスト10を求めるAppleScriptです。
自分の開発環境(MacBook Pro Retina 2012, Core i7 2.6GHz)で10日間のアクセス履歴を処理して0.8秒程度です。
以前のSafariではplistでヒストリを管理していましたが、気づいたらSqliteのDBで管理するように変わっていたので(Safari 10あたりで?)、よろしく抽出して加工してみました。おそらく、最低限の情報のみ抽出することで現状の半分ぐらいの処理時間で処理できるようになるとは思うのですが、汎用性を持たせるために現状のレベルにまとめています。
計算結果が当たり前すぎて予想よりはるかに面白くなかったので、そのことに逆に驚きました。
AppleScript名:Safariの履歴を読み込んでBest 10を求める。「その他」計算機能つき.scptd |
— – Created by: Takaaki Naganoya – Created on: 2020/04/29 — – Copyright © 2020 Piyomaru Software, All Rights Reserved — use AppleScript version "2.7" — (10.13) or later use scripting additions use framework "Foundation" property |NSURL| : a reference to current application’s |NSURL| script spd property sList : {} property nList : {} property sRes : {} end script set aRes to calcSafariHistoryBest10Domain(10) of me –> {{theName:"piyocast.com", numberOfTimes:1100}, {theName:"www.youtube.com", numberOfTimes:710}, {theName:"twitter.com", numberOfTimes:354}, {theName:"www.google.com", numberOfTimes:331}, {theName:"syosetu.com", numberOfTimes:199}, {theName:"github.com", numberOfTimes:140}, {theName:"developer.apple.com", numberOfTimes:139}, {theName:"appstoreconnect.apple.com", numberOfTimes:121}, {theName:"xxxxxxxxxxxxx", numberOfTimes:106}, {theName:"Other", numberOfTimes:847}} on calcSafariHistoryBest10Domain(daysBefore) –現在日時のn日前を求める set origDate to (current date) – (daysBefore * days) set dStr to convDateObjToStrWithFormat(origDate, "yyyy-MM-dd hh:mm:ss") of me set aDBpath to "~/Library/Safari/History.db" set pathString to current application’s NSString’s stringWithString:aDBpath set newPath to pathString’s stringByExpandingTildeInPath() set aText to "sqlite3 " & newPath & " ’SELECT datetime(history_visits.visit_time+978307200, \"unixepoch\", \"localtime\"), history_visits.title || \" @ \" || substr(history_items.URL,1,max(length(history_items.URL)*(instr(history_items.URL,\" & \")=0),instr(history_items.URL,\" & \"))) as Info FROM history_visits INNER JOIN history_items ON history_items.id = history_visits.history_item where history_visits.visit_time>(julianday(\"" & dStr & "\")*86400-211845068000) ORDER BY visit_time ASC LIMIT 999999;’" set (sRes of spd) to do shell script aText set (sList of spd) to (paragraphs of (sRes of spd)) set (nList of spd) to {} repeat with i in (sList of spd) set j to contents of i –Parse each field set j2 to parseByDelim(j, {"|", "@ "}) of me –Calculate URL’s domain only set j3 to contents of last item of j2 set aURL to (|NSURL|’s URLWithString:j3) if aURL = missing value then set j4 to "" else set j4 to (aURL’s |host|()) as string end if set the end of (nList of spd) to j4 end repeat –登場頻度でURLを集計 set aList to countItemsByItsAppearance((nList of spd)) of me –Best 10の計算のために10位以下をまとめる set best9 to items 1 thru 9 of aList set best10 to items 10 thru -1 of aList set otherTimes to 0 repeat with i in best10 set otherTimes to otherTimes + (numberOfTimes of i) end repeat set the end of best9 to {theName:"Other", numberOfTimes:otherTimes} return best9 end calcSafariHistoryBest10Domain on parseByDelim(aData, aDelim) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to aDelim set dList to text items of aData set AppleScript’s text item delimiters to curDelim return dList end parseByDelim –出現回数で集計 on countItemsByItsAppearance(aList) set aSet to current application’s NSCountedSet’s alloc()’s initWithArray:aList set bArray to current application’s NSMutableArray’s array() set theEnumerator to aSet’s objectEnumerator() repeat set aValue to theEnumerator’s nextObject() if aValue is missing value then exit repeat bArray’s addObject:(current application’s NSDictionary’s dictionaryWithObjects:{aValue, (aSet’s countForObject:aValue)} forKeys:{"theName", "numberOfTimes"}) end repeat –出現回数(numberOfTimes)で降順ソート set theDesc to current application’s NSSortDescriptor’s sortDescriptorWithKey:"numberOfTimes" ascending:false bArray’s sortUsingDescriptors:{theDesc} return bArray as list end countItemsByItsAppearance on convDateObjToStrWithFormat(aDateO as date, aFormatStr as string) set aDF to current application’s NSDateFormatter’s alloc()’s init() set aLoc to current application’s NSLocale’s currentLocale() set aLocStr to (aLoc’s localeIdentifier()) as string aDF’s setLocale:(current application’s NSLocale’s alloc()’s initWithLocaleIdentifier:aLocStr) aDF’s setDateFormat:aFormatStr set dRes to (aDF’s stringFromDate:aDateO) as string return dRes end convDateObjToStrWithFormat |
More from my site
(Visited 43 times, 1 visits today)