Защо редът Click ndx . . . твърдението няма ефект в този Applescript?

Рутината "on switchDir" има за цел да намери всеки елемент от пътя, подаден като "директория", и да щракне върху него, така че пътят на директорията да се гмурне, за да достигне желаната крайна изходна директория.

При активиране на желания ред с мишката. както обикновено, той трябва да бъде щракнат два пъти, за да го изберете!

Това е кодът само на "on switchDir":

on switchDir(directory, appName, selectDefault, createIt)
    local compname, bootvolume
    set compname to get computer name of (system info)
    set bootvolume to get boot volume of (system info)
    if directory is equal to "~" then set directory to system attribute ("HOME")
    if directory starts with "~/" then set directory to (system attribute ("HOME")) & text 2 through -1 of (get directory)
    if not checkPathExists(directory) then
        if createIt then
            do shell script ("mkdir -p " & (POSIX path of directory))
        else
            return false
        end if
    end if
    if directory begins with "/" then
        set directory to bootvolume & (get directory)
    end if
    tell application "System Events" to tell (process "iTunes"'s front window)
        delay 1
        click pop up button 1 of group 1 -- selects the drop-down box above the directory listing
        set max to the count of menu items of menu 1 of pop up button 1 of group 1 -- number of items in the drop-down menu
        set ndx to 1
        repeat while ndx ≤ max
            if the title of group 1's pop up button 1's menu 1's menu item ndx as string is equal to compname then -- found the absolute top-level directory
                click group 1's pop up button 1's menu 1's menu item ndx - so choose it and go to next part of navigation
                exit repeat
            else -- keep looking
                set ndx to (get ndx) + 1
            end if
        end repeat
        if ndx > max then error "Never found " & compname
        set thePath to every item of my splitString(directory, "/") -- thePath equals every individual folder in the path's name in order
        repeat with dir in thePath
            set max to the (count of rows in outline 1 of scroll area 1 of splitter group 1 of group 1) -- max equals the number of rows in the "directory contents" list box
            log max
            set ndx to 2 -- row 1 is just the colum titles
            repeat while ndx ≤ max
                log the value of text field 1 of UI element 1 of row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 as string
                log the value of text field 1 of UI element 1 of row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 as string is equal to dir as string
                if the value of text field 1 of UI element 1 of row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 as string is equal to dir as string then -- this is the row we want!
                    log "found " & dir & " at row " & ndx as string
                    select row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 -- included to make sure the reference in the "click" statement is correct
                    click row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 -- supposed to "click" the desired folder name to choose it and dive deeper, BUT IT DOESN'T ACTUALLY DO THAT!
                    exit repeat -- apparently never executed because the loop keeps going past finding the desired directory's name and crashes at the first blank row!
                else
                    set ndx to (get ndx) + 1
                end if
                if ndx > max then error "Never found " & dir
             end repeat
        end repeat
    end tell
    error "success"
    return true
end switchDir

Грешката възниква в „on switchDir“, останалата част от кода е включена само така, че кодът да се изпълни под „Редактор на скриптове“. И двата „Щракнете ред ndx . . . .“ и операторът "exit repeat" след него очевидно никога не се изпълняват, тъй като цикълът продължава да работи след регистриране на "found". . . . и следователно се срива на първия празен ред в списъчното поле. Намереното (с кавичките) може да се използва като дума за търсене за намиране на кода.

Следва пълният, изпълняваем код на приложението:

on splitString(theString, theDelimiter)
    set oldDelimiters to AppleScript's text item delimiters
    set AppleScript's text item delimiters to theDelimiter
    set theArray to every text item of theString
    set AppleScript's text item delimiters to oldDelimiters
    return theArray
end splitString

on checkPathExists(thePath)
    if thePath is equal to "~" then set thePath to system attribute ("HOME")
    if thePath starts with "~/" then set thePath to (system attribute ("HOME")) & text 2 through -1 of (get thePath)
    try
        POSIX file thePath as alias
        return true
    on error
        return false
    end try
end checkPathExists

on switchDir(directory, appName, selectDefault, createIt)
    local compname, bootvolume
    set compname to get computer name of (system info)
    set bootvolume to get boot volume of (system info)
    if directory is equal to "~" then set directory to system attribute ("HOME")
    if directory starts with "~/" then set directory to (system attribute ("HOME")) & text 2 through -1 of (get directory)
    if not checkPathExists(directory) then
        if createIt then
            do shell script ("mkdir -p " & (POSIX path of directory))
        else
            return false
        end if
    end if
    if directory begins with "/" then
        set directory to bootvolume & (get directory)
    end if
    tell application "System Events" to tell (process "iTunes"'s front window)
        delay 1
        click pop up button 1 of group 1 -- selects the drop-down box above the directory listing
        set max to the count of menu items of menu 1 of pop up button 1 of group 1 -- number of items in the drop-down menu
        set ndx to 1
        repeat while ndx ≤ max
            if the title of group 1's pop up button 1's menu 1's menu item ndx as string is equal to compname then -- found the absolute top-level directory
                click group 1's pop up button 1's menu 1's menu item ndx - so choose it and go to next part of navigation
                exit repeat
            else -- keep looking
                set ndx to (get ndx) + 1
            end if
        end repeat
        if ndx > max then error "Never found " & compname
        set thePath to every item of my splitString(directory, "/") -- thePath equals every individual folder in the path's name in order
        repeat with dir in thePath
            set max to the (count of rows in outline 1 of scroll area 1 of splitter group 1 of group 1) -- max equals the number of rows in the "directory contents" list box
            log max
            set ndx to 2 -- row 1 is just the colum titles
            repeat while ndx ≤ max
                log the value of text field 1 of UI element 1 of row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 as string
                log the value of text field 1 of UI element 1 of row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 as string is equal to dir as string
                if the value of text field 1 of UI element 1 of row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 as string is equal to dir as string then -- this is the row we want!
                    log "found " & dir & " at row " & ndx as string
                    select row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 -- included to make sure the reference in the "click" statement is correct
                    click row ndx of outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1 -- supposed to "click" the desired folder name to choose it and dive deeper, BUT IT DOESN'T ACTUALLY DO THAT!
                    exit repeat -- apparently never executed because the loop keeps going past finding the desired directory's name and crashes at the first blank row!
                else
                    set ndx to (get ndx) + 1
                end if
                if ndx > max then error "Never found " & dir
             end repeat
        end repeat
    end tell
    error "success"
    return true
end switchDir

set directory to "/Users/bryandunphy/Music"
try
    tell application "iTunes" to quit
end try
tell application "System Events"
    key down option
    tell application "iTunes" to activate
    key up option
    repeat until process "iTunes" exists
        delay 0.5
    end repeat
    click process "iTunes"'s window 1's button 2
    my switchDir(directory, "iTunes", false, true)
    delay 2
    set libraryName to value of text field "Save As:" of window "New iTunes Library" of process "iTunes"
    delay 2
    click process "iTunes"'s window "New iTunes Library"'s button "Save"
end tell
return libraryName

Всяка идея за причината за грешката и/или как да я поправите ще бъде високо оценена.


person Bryan Dunphy    schedule 14.03.2017    source източник
comment
Това е доста плътно и се съмнявам, че някой ще иска да го стартира на своята машина, за да го тества от страх да не обърка библиотеката си в iTunes. Какво се опитвате да постигнете, като щракнете върху реда? Казвате, че изявленията log "found" и select row над click работят, но click и exit repeat не се спазват? Като за начало, не мисля, че имате нужда от as string част от log "found " & dir & " at row " & ndx as string. Вече свързвате низ.   -  person pipwerks    schedule 16.03.2017
comment
@pipwerks Щракването няма ефект и повторението за изход също няма, тъй като цикълът се проявява при грешки при опит за достъп до първия празен ред.   -  person Bryan Dunphy    schedule 16.03.2017
comment
Да, но какво се опитвате да постигнете, като щракнете върху реда? Не ми е ясно какво е row или защо искате да щракнете върху него. Възможно е да има други начини за обработка на действието, като например натискане на клавиш. Но първият ред за отстраняване на неизправности е да опростите възможно най-много - публикацията ви по-горе е много гъста, без обяснение какво се случва (напр. set max to the count of menu items of menu 1 of pop up button 1 of group 1 ). Можете ли да премахнете скрипта си, за да изолирате счупения repeat?   -  person pipwerks    schedule 16.03.2017
comment
Кодът се опитва да избере желаната директория и да щракне двукратно върху нея, така че цикълът да може да повтори това за всеки елемент на пътя, докато се достигне крайната директория на местоназначение.   -  person Bryan Dunphy    schedule 16.03.2017
comment
Това Е най-доброто, което мога да направя, за да го опростя и все пак да го използвам в контекста, за съжаление.   -  person Bryan Dunphy    schedule 16.03.2017
comment
какво връща log "found " & dir & " at row " & ndx as string? Показва ли се както очаквате?   -  person pipwerks    schedule 16.03.2017
comment
@pipwerks Да, така е. Например, пише Намерен Macintosh HD на ред 5. Точно преди да не успее да се потопи в него.   -  person Bryan Dunphy    schedule 16.03.2017
comment
Благодаря, че добавихте подробности към публикацията си. Каква версия на iTunes и macOS? Не мога да подмина click pop up button 1 of group 1 в Сиера с най-новата версия на iTunes. Освен това вместо двойно щракване, опитайте CMD-o keystroke o using {command down}   -  person pipwerks    schedule 16.03.2017
comment
Най-новият iTunes под El Capitan. Софтуер на трета страна, от който завися поради увреждане, иска $nnn за версия, съвместима със Sierra, така че не мога да направя безплатното надграждане.   -  person Bryan Dunphy    schedule 16.03.2017
comment
@pipwerks Command-O работи! Но все пак бих искал да знам официалния начин, по който трябва да се направи? Това е без използване на клавишна комбинация, която, доколкото ми е известно, НЕ е документирана НИКЪДЕ!   -  person Bryan Dunphy    schedule 17.03.2017


Отговори (1)


Преработих вашата функция onSwitchDir, за да я направя да работи на моята машина и да я направя по-четима.

Добавих също много регистриране, за да помогна за отстраняване на неизправности, не се колебайте да изтриете.

on switchDir(directory, appName, selectDefault, createIt)

    local compname, bootvolume
    set sysInfo to (system info) -- cache value to reduce processing time
    set compname to get computer name of sysInfo
    log "compname: " & compname
    set bootvolume to get boot volume of sysInfo
    log "bootvolume: " & bootvolume
    if directory is equal to "~" then set directory to system attribute ("HOME")
    if directory starts with "~/" then set directory to (system attribute ("HOME")) & text 2 through -1 of (get directory)

    if not checkPathExists(directory) then
        if createIt then
            do shell script ("mkdir -p " & (POSIX path of directory))
        else
            return false
        end if
    end if

    if directory begins with "/" then
        set directory to bootvolume & (get directory)
    end if

    tell application "System Events" to tell (process "iTunes"'s front window)

        -- ensure view is set to expanded view
        try
            click pop up button 1 of group 1
        on error
            key code 81 using {command down} -- expand view
            delay 2 -- esnure it finishes expanding before continuing
        end try

        -- name the item, making the code more readable
        set dropDownMenuBtn to menu 1 of pop up button 1 of group 1

        click dropDownMenuBtn -- selects the drop-down box above the directory listing

        -- Set drop-down menu to go to system's root folder
        -- Variation of solution from http://stackoverflow.com/questions/13415994/how-to-get-the-number-of-items-in-a-pop-up-menu-without-opening-it-using-applesc
        tell pop up button 1 of group 1
            if value of it is not equal to compname then
                set menuItemTitles to name of menu items of menu 1
                --check if the menu item exists
                if compname is in menuItemTitles then
                    --menu item exists; click on it
                    click menu item compname of menu 1
                    log "yay! found it! setting menu to item " & compname
                else
                    --the menu item to select doesn't exist; hide the menu
                    log "bummer! " & compname & " doesn't exist"
                    key code 53
                end if
            else
                log "yay! menu already set to " & compname
            end if
        end tell

        -- Make iTunes dialog navigate to root folder
        set thePath to every item of my splitString(directory, "/") -- thePath equals every individual folder in the path's name in order
        log "thePath: " & thePath

        set isFound to false -- so we can exit the repeat loop when needed

        repeat with dir in thePath

            if isFound is false then

                -- set reference to UI element for readability
                set theOutline to outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of group 1

                set max to the (count of rows in theOutline) -- max equals the number of rows in the "directory contents" list box
                log "max for " & dir & ": " & max

                set ndx to 2 -- row 1 is just the column titles

                repeat while ndx ≤ max

                    -- set reference to item for readability
                    set theRow to row ndx of theOutline

                    -- set reference to item for readability                    
                    set theElement to text field 1 of UI element 1 of theRow

                    -- if we have found the appropriate item
                    if the value of theElement is equal to dir as string then

                        -- set focus so we can use keyboard commands on it
                        set value of attribute "AXFocused" of theOutline to true

                        -- select the item in the list
                        select theRow

                        -- set boolean so we can avoid re-running the repeat loop
                        set isFound to true

                        -- exit inner repeat
                        exit repeat

                    else

                        set ndx to (get ndx) + 1

                    end if

                    if ndx > max then error "Never found " & dir

                end repeat

            else

                -- exit outer repeat
                exit repeat

            end if

        end repeat

        -- CMD-o to open the selected directory
        keystroke "o" using {command down}

    end tell

end switchDir

set directory to "/Users/username/Music"

try
    tell application "iTunes" to quit
end try

tell application "System Events"
    key down option
    tell application "iTunes" to activate
    key up option
    repeat until process "iTunes" exists
        delay 0.5
    end repeat
    click process "iTunes"'s window 1's button 2
    my switchDir(directory, "iTunes", false, true)
    delay 0.5
    set libraryName to value of text field "Save As:" of window "New iTunes Library" of process "iTunes"
    delay 0.5
    click process "iTunes"'s window "New iTunes Library"'s button "Save"
end tell
return libraryName

Забележителни промени:

  • Промених обработката за излизане от повторения цикъл; вашият код имаше недостатък, който би накарал повтарящия се цикъл да продължи да излиза дори след като exit repeat е издаден
  • Намалих броя на обажданията до System Info, което ускорява скрипта
  • Създадох променливи като препратки към елементи като menu 1 of pop up button 1 of group 1, правейки скрипта по-малко плътен и по-лесен за четене
  • Промених метода за избор на елемент от падащото меню (смятам, че този код е по-лесен за следване)
  • Добавих командата keystroke "o", но я поставих СЛЕД цикъла за повторение (няма да работи, докато е в цикъла по някаква причина)
  • Добавих малко обработка на грешки, за да накарам скрипта да работи на моята система; например, ако прозорецът Нова библиотека беше отворен, но в компактен режим, препратката group 1 би причинила грешка. Като се уверя, че прозорецът е разширен, group 1 се разрешава и вече не получавам грешката.

Обърнете внимание, че резултатът от този скрипт е предупреждение на iTunes, че не може да създаде нова библиотека на исканото място. Вярвам, че това е така, защото имам само фрагмент от целия ви сценарий. Предполагам, че имате другия край на кода, което би разрешило проблема. Ако е така, трябва да можете да включите тези промени във вашия проект без много усилия.

person pipwerks    schedule 17.03.2017
comment
Бихте ли коментирали редовете с ‹число› на кода на ключа, за да посочите какъв ключ всъщност се изпраща? Също така, има ли някъде списък с ключови кодове? - person Bryan Dunphy; 17.03.2017
comment
escape, това е описано в URL адреса, който предоставих. - person pipwerks; 17.03.2017
comment
ключов код 53 е escape, както е обяснено тук (URL в кода по-горе) stackoverflow.com/questions/13415994/. Другият ключов код е 81, което е =. Има много ресурси за ключови кодове онлайн - person pipwerks; 17.03.2017
comment
С излизането на 12.6 дори ТОЗИ код е повреден! Сега той отваря нов диалогов прозорец за отваряне, вместо да остане в текущия диалогов прозорец, веднага щом намери първата директория за повторение с dir в thePath! Да пусна ли нов въпрос или какво? - person Bryan Dunphy; 23.03.2017
comment
Кодът, който публикувах, все още работи за мен с iTunes 12.6. Ако можете да изолирате конкретната точка, където скриптът се проваля, публикувайте го като нов въпрос. - person pipwerks; 24.03.2017