2013-08-12 22 views
5

Z tego prostego kawałka AppleScript mogę wymienić nazwy wszystkich piosenek w ciągu iTunesJak to zrobić masz wyjście z JavaScript w Javie przy użyciu ScriptEngine

tell application "iTunes" 
    set mainLibrary to library playlist 1 
    repeat with nexttrack in (get every track of mainLibrary) 
     try 
      name of nexttrack 
     end try 
    end repeat 
end tell 

I następnie uruchomić go jako Java kodu 7 za pomocą ScriptEngine jednak jest tylko oczywiste, jak uzyskać wynik skryptu, który w tym przypadku jest tylko nazwą ostatniego utworu.

StringBuilder script =new StringBuilder(); 
    script.append("tell application \"iTunes\"\n"); 
    script.append("set mainLibrary to library playlist 1\n"); 
    script.append("repeat with nexttrack in (get every track of mainLibrary)\n"); 
    script.append("try\n"); 
    script.append("name of nexttrack\n"); 
    script.append("end try\n"); 
    script.append("end repeat\n"); 
    script.append("end tell\n"); 
    ScriptEngineManager mgr = new ScriptEngineManager(); 
    ScriptEngine engine = mgr.getEngineByName("AppleScript"); 
    System.out.println(engine.eval(script.toString())); 

How do can I capture the name of all tracks , i.e all output from the script. I assume I have to redirect standard out to a Reader, but cannot see how to do it. 

Aktualizacja:

I found this article 

http://www.informit.com/articles/article.aspx?p=696621&seqNum=6

Ale aktualizowanie kodem do

StringBuilder script =new StringBuilder(); 
script.append("tell application \"iTunes\"\n"); 
script.append("set mainLibrary to library playlist 1\n"); 
script.append("repeat with nexttrack in (get every track of mainLibrary)\n"); 
script.append("try\n"); 
script.append("name of nexttrack\n"); 
script.append("end try\n"); 
script.append("end repeat\n"); 
script.append("end tell\n"); 
ScriptEngineManager mgr = new ScriptEngineManager(); 
ScriptEngine engine = mgr.getEngineByName("AppleScript"); 
StringWriter sw = new StringWriter(); 
PrintWriter pw = new PrintWriter(sw); 
StringWriter swError = new StringWriter(); 
PrintWriter pwError = new PrintWriter(swError); 
engine.getContext().setWriter(pw); 
engine.getContext().setErrorWriter(pwError); 

System.out.println(engine.eval(script.toString())); 
System.out.println("************* engine:"+sw.getBuffer()); 
System.out.println("************* engine error:"+swError.getBuffer()); 

Wystarczy wyjść

See You on the Other Side (short) 
************* engine: 
************* engine error: 

Widać wyraźnie, że skrypt działa tak, jak eval pokazuje nazwę ostatniego utworu, ale nic nie dostaję od przekierowanych pisarzy. Zastanawiasz się, czy to rzeczywiście działa na applescript?

Aktualizacja 2 pisałem test w JavaScript i znaleźć ustawienie pisarze wyszło na to, więc Im myśli, że albo

  1. Jest coś zepsute w silnik skryptowy dla Applescript (IM przy użyciu najnowszej kompilacji 1.7.0_40-ea-b29) wersji wcześnie dostępu Java 7 na OSX)
  2. My Applescript jest źle, to znaczy zamiast po prostu nazwa nexttrack powinienem robić coś echo nazwy nexttrack faktycznie zrobić i t iść do stdout.

Chciałbym myśleć (2) był problem, ale canot mogę znaleźć żadnego odniesienia do wpisywanie tekstu w Applescript, echo nie jest poprawnym poleceniem i druku komenda ma rzeczywiście starają się drukiem do drukarki zamiast drukować na stdout jak miałoby to w Java lub C

Update 3 więc nie mogłem dostać tej pracy, a teraz zastanawiasz się, czy kiedykolwiek Applescript tylko pisze zwracanej wartości. Znalazłem przykład użycia stdout (a przynajmniej tak myślałem), ale myślę, że to tylko konwencja nazewnictwa, a tak naprawdę wszystko, co robi, to nieustanne dołączanie danych do zmiennej i ostatecznie to zwracają.

Więc zrobiłem to coś działa za pomocą następującego skryptu zapisanego w pliku, a następnie wykorzystywane w Javie z engine.eval (nowy java.io.FileReader („filename”)

tell application "iTunes" 
    set output to "" 
    set mainLibrary to library playlist 1 
    repeat with nexttrack in (get every track of mainLibrary) 
     if (class of nexttrack is file track) then 
      try 
       set trackname to name of nexttrack 
       set loc to location of nexttrack 
       set locpath to POSIX path of loc 
       set persistid to persistent ID of nexttrack 
       set nextline to trackname & "::" & locpath & "::" & persistid 
       set output to output & "\n" & nextline 
      end try 
     end if 
    end repeat 
    copy output to stdout 
end tell 

ale to faktycznie nie rozwiązuje pierwotnego pytania, a jedynym problemem jest to, że jeśli wystąpi jakikolwiek błąd, to nic nie dostanę, podczas gdy jeśli nie uda mi się go przeczytać w iTuneslibrary i korzystam ze stdout, to przynajmniej dostanę połowę dane z powrotem.

Odpowiedz

2

Aby odpowiedzieć na twoje oryginalne pytanie, otrzymasz zwrot "cokolwiek powrócisz" na końcu skryptu. Jeśli nie masz konkretnej instrukcji "return", domyślnie otrzymasz wynik z ostatniej akcji (która w twoim przypadku jest ostatnią iteracją pętli powtarzania). Dlatego jeśli potrzebujesz więcej niż ostatnia akcja zwrócona, musisz utworzyć wartość zwracaną w swoim skrypcie, a następnie zwrócić ją na końcu.

ale to nie robi właściwie rozwiązać oryginalne pytanie, a jeden Problem z nim jest to, że jeśli jest jakiś błąd potem przyzwyczajenie się nic pleców, natomiast jeżeli nie udało się w połowie czytania mojego iTuneslibrary i byłem używając stdout, otrzymam co najmniej połowę danych. To jest nieprawidłowe. Blok try wokół kodu sprawi, że applescript zignoruje błędy i będzie kontynuowany, więc wszystko, co zbieramy, ale nie błąd, zostanie zwrócone.

Pamiętaj, że masz kilka błędów w swoim najnowszym kodzie AppleScript. Szczególnie ta linia nie ma sensu, ponieważ applescript nie wie, co to jest stdout. Twój komentarz jest nieprawidłowy.

Oto, co musisz zrobić. Jak wspomniano, używasz "return", aby zwrócić coś. Więc wyczyściłem twój kod. Spowoduje to umieszczenie każdej linii powtórzenia pętli w osobnej linii zmiennej wyjściowej, którą zwrócisz na końcu kodu, który możesz następnie przeanalizować po wprowadzeniu do kodu javascript. Wypróbuj to ...

tell application "iTunes" 
    set output to "" 
    set mainLibrary to library playlist 1 
    repeat with nexttrack in (get every track of mainLibrary) 
     if (class of nexttrack is file track) then 
      try 
       set trackname to name of nexttrack 
       set loc to location of nexttrack 
       set locpath to POSIX path of loc 
       set persistid to (persistent ID of nexttrack) as text 
       set nextline to trackname & "::" & locpath & "::" & persistid & return 
       set output to output & nextline 
      end try 
     end if 
    end repeat 
end tell 
return output 
+0

Dziękuję, rozumiem twoją odpowiedź. Ale nie rozumiem, czy applescript może być użyty do zapisywania danych wyjściowych na standardowe wyjście podczas działania, czy też nigdy nie może zapisać na standardowe wyjście, z wyjątkiem napisania ostatniej instrukcji value/return, gdy skrypt się kończy. W moim przypadku jest to importnat, ponieważ biblioteka iTunes może zawierać 50 000 utworów, a zatem dane wyjściowe będą zawierać 50 000 miejsc i nazw utworów. –

+0

Nie, nie można pisać na standardowe wyjście, gdy skrypt się rozwija. Możesz napisać tylko raz na końcu skryptu, jak wyjaśniono. Możesz jednak zapisywać do pliku wiersz po wierszu w pętli powtarzania, a następnie odczytać ten plik z kodu javascript po zakończeniu skryptu ... jeśli jest to potrzebne. – regulus6633

+0

To faktycznie z kodu java, to wstyd mam nadzieję, że mogę uniknąć tworzenia plików tymczasowych, wydaje się naprawdę dziwne, że instrukcja dla osascripta wydaje się sugerować, że wyjście jest napisane przy omawianiu opcji -e –