2

AppleScriptイメージをマウントするために を書きましたが、起動SparseBundle時に正確に実行されるようにします。Time Machine

現在、Time Machine がAppleScriptusingon idleステートメントで実行されているかどうかを定期的に確認しています。

on idle
    ....
    return <interval>
end idle

これは堅牢な方法ではありません。私の意見では、イベントにイベントトリガーを追加するApplication Launch方が良い方法です。

助けていただけますか?

Objective-CまたはPythonサンプルコード(私が好む)Pythonは大歓迎です。

4

3 に答える 3

6

あなたが探しているのは、NSDistributedNotificationCenterまたはNSWorkspace です。これらのココア クラスは、アプリケーション イベントの通知を投稿します。ワークスペースの場合、アプリケーションの起動、ドライブのマウントなどです。

Python でこれを行うには、基本的に Apple のココア クラスの Python バインディングであるPyObjCが必要です。ドキュメンテーションは彼らのウェブサイトでまばらであり、ドキュメンテーションは基本的に Apple docs と同じであるため、pyobjc API と cocoa API の違いのみが含まれているため、理由があります。目的の c API がどのように Python に変換されるかを理解していれば、問題ありません。ここをチェックしてください:http://pyobjc.sourceforge.net/documentation/pyobjc-core/intro.html

Python を使用して分散通知をリッスンする例を以下に示します。以下のコードは、基本的にオブザーバーを追加し、iTunes 通知をリッスンします。同様の構造に従うことができますが、代わりに NSWorkspace のオブザーバーを追加します。何を聞くべきかを把握するために、システムを通過するすべての通知を表示するアプリケーションがあります。それは通知ウォッチャーと呼ばれます。これを使用して、何を聞くべきかを判断します。目的の C コードを Python に変換することもできます。

以下のコードが行っていること

  1. PyObjC で定義されているように、NSObject から継承する新しいクラスを定義します
  2. 実際の通知を渡して出力するメソッドを定義します
  3. Foundation.NSDistributedNotificationCenter.defaultCenter のインスタンスを作成します
  4. GetSongs のインスタンスを作成します
  5. オブザーバーを登録し、クラス、通知を受信したときに呼び出されるメソッド、監視するアプリケーションとイベント、つまり「com.apple.iTunes.playerInfo」を渡します
  6. イベントループを実行し、

つまずくことがありますが、属性 (目的の c 属性) へのアクセスは、python 属性へのアクセスと同じようには機能しません。つまり、python では、Pythonclass_name.attで目的の c を実行します。関数のように呼び出す必要があります。つまり、以下の例から:song.userInfo()

import Foundation
from AppKit import *
from PyObjCTools import AppHelper

class GetSongs(NSObject):
    def getMySongs_(self, song):
        print "song:", song
        song_details = {}
        ui = song.userInfo()
        print 'ui:', ui
        for x in ui:
            song_details[x] = ui.objectForKey_(x)
        print song_details

nc = Foundation.NSDistributedNotificationCenter.defaultCenter()
GetSongs = GetSongs.new()
nc.addObserver_selector_name_object_(GetSongs, 'getMySongs:', 'com.apple.iTunes.playerInfo',None)

NSLog("Listening for new tunes....")
AppHelper.runConsoleEventLoop()

これが実際の出力の例です... (YES BRITNEY ROCKS!, NOT! ;)

song NSConcreteNotification 0x104c0a3b0 {name = com.apple.iTunes.playerInfo; object = com.apple.iTunes.player; userInfo = {
    Album = Circus;
    "Album Rating" = 0;
    "Album Rating Computed" = 1;
    Artist = "Britney Spears";
    "Artwork Count" = 1;
    Genre = Pop;
    "Library PersistentID" = 8361352612761174229;
    Location = "file://localhost/Users/izze/Music/iTunes/iTunes%20Music/Britney%20Spears/Circus/02%20Circus.mp3";
    Name = Circus;
    PersistentID = 4028778662306031905;
    "Play Count" = 0;
    "Play Date" = "2010-06-26 08:20:57 +0200";
    "Player State" = Playing;
    "Playlist PersistentID" = 7784218291109903761;
    "Rating Computed" = 1;
    "Skip Count" = 1;
    "Skip Date" = "2010-06-26 12:20:57 +0200";
    "Store URL" = "itms://itunes.com/link?n=Circus&an=Britney%20Spears&pn=Circus";
    "Total Time" = 192444;
    "Track Count" = 16;
    "Track Number" = 2;
}}
ui {
    Album = Circus;
    "Album Rating" = 0;
    "Album Rating Computed" = 1;
    Artist = "Britney Spears";
    "Artwork Count" = 1;
    Genre = Pop;
    "Library PersistentID" = 8361352612761174229;
    Location = "file://localhost/Users/izze/Music/iTunes/iTunes%20Music/Britney%20Spears/Circus/02%20Circus.mp3";
    Name = Circus;
    PersistentID = 4028778662306031905;
    "Play Count" = 0;
    "Play Date" = "2010-06-26 08:20:57 +0200";
    "Player State" = Playing;
    "Playlist PersistentID" = 7784218291109903761;
    "Rating Computed" = 1;
    "Skip Count" = 1;
    "Skip Date" = "2010-06-26 12:20:57 +0200";
    "Store URL" = "itms://itunes.com/link?n=Circus&an=Britney%20Spears&pn=Circus";
    "Total Time" = 192444;
    "Track Count" = 16;
    "Track Number" = 2;
}
{u'Album Rating Computed': 1, u'Album': u'Circus', u'Rating Computed': True, u'Name': u'Circus', u'Artist': u'Britney Spears', u'Track Number': 2, u'Skip Date': 2010-06-26 12:20:57 +0200, u'Library PersistentID': 8361352612761174229L, u'Player State': u'Playing', u'Total Time': 192444L, u'Genre': u'Pop', u'Playlist PersistentID': 7784218291109903761L, u'Album Rating': 0, u'Location': u'file://localhost/Users/izze/Music/iTunes/iTunes%20Music/Britney%20Spears/Circus/02%20Circus.mp3', u'Skip Count': 1, u'Track Count': 16L, u'Artwork Count': 1, u'Play Date': 2010-06-26 08:20:57 +0200, u'PersistentID': 4028778662306031905L, u'Play Count': 0, u'Store URL': u'itms://itunes.com/link?n=Circus&an=Britney%20Spears&pn=Circus'}
于 2010-12-06T21:45:51.227 に答える
4

これは、Objc-C で行うのはそれほど難しくありません。NSWorkspace および NSNotificationCenter を介して、すべてのアプリケーションの通知にアクセスできます。オブジェクトを作成し、タイプ NSWorkspaceDidTerminateApplicationNotification の通知用のメソッドの 1 つを登録します。何かのようなもの:

@interface NotificationObserver : NSObject { }
- (void) applicationDidLaunch:(NSNotification*)notification;
@end

@implementation NotificationObserver : NSObject
- (void) applicationDidLaunch:(NSNotification*)notification
{
  // Check the notification to see if Time Machine is being launched.
}
@end

void watch(void)
{
  NSNotificationCenter* notificationCenter
    = [[NSWorkspace sharedWorkspace] sharednotificationCenter];
  NotificationObserver* observer = [[NotificationObserver alloc] init];
  [notificationCenter addObserver:observer
                         selector:@selector(applicationDidTerminate:)
                             name:@"NSWorkspaceDidTerminateApplicationNotification"
                           object:nil];
}
于 2010-12-01T22:25:53.213 に答える
0

これはあなたの質問に対する答えではありませんが、あなたの問題を解決するかもしれません。

ディスクイメージをマウントした後、AppleScriptにTime Machineを起動させてみませんか?次に、Time Machineを直接起動するのではなく、常にスクリプトを介してTimeMachineを呼び出します。Time MachineアイコンをAppleScriptファイルに貼り付け、「Time Machine」という名前を付けて、錯覚を完成させることもできます。:-)

于 2010-12-06T08:42:35.077 に答える