Scripting itunes without applescript? - macos

I am looking for a way of scripting iTunes using something else then AppleScript. I want to mass-manipulate the title-name and artist of tracks. Using some id3-tool won't help, because as far as I know the iTunes database will not update, if I don't use iTunes for manipulating this information. As I don't know how to code with AppleScript and don't really have the time to dive into this, I wonder: is there any way to do this task using javascript, lua, bash or php?
thanks,

I suggest you to learn AppleScript, at least for a day. The point is, the inter-GUI-app communication in OS X is done via Apple Events, whose construct follows that of its main language AppleScript. There are many bridges which allow you to call Apple Events from various languages, but you need to understand the concept of Apple Events first. So, at least you need a bit of familiarity with AppleScript.
This is just as in the case of Cocoa: you can code Cocoa apps in many languages, but most of the documentation and the concept are based on Objective-C. So you need to at least a bit of familiarity with Objective-C before coding Cocoa in other languages.
So, let me give you a very very short overview of Apple Events/ AppleScript system.
Each app implements an object-oriented system and exposes it to the outside world as a dictionary, which you can read with AppleScript Editor. Open the AppleScript Editor, and choose File → Open Dictionary, and choose iTunes. There, you see the list of commands, classes, methods in those classes, etc. Then, from AppleScript or Ruby or Lua, you access these objects and methods.
Suppose you want to rename the selected entries of iTunes from "A-B" to "B-A". Then the code would be
set text item delimiters to "-"
tell application "iTunes" -- following statements are targeted to iTunes
repeat with entry in selection -- "selection" is a concept implemented in iTunes
set s to name of entry -- copy the name of entry to a local string s
set x to text items of s -- split the string s to a list according to text item delimiters
set y to {item 2 of x, item 1 of x} -- construct another list
set name of entry to y as string -- set the name. Note that "as string" adds the delimiters
end repeat
end tell
Yes the grammar of AppleScript is a bit weird, but it basically has one-to-one correspondence with a regular imperative language. Just refer to the official language guide if you're confused. And text operations in AppleScript without a good OSAX (AppleScript's extension system) is a chore. So I agree it's not a bad idea to first get familiar with the concept of AppleScript, and then use it from Ruby or any of your favorite languages.
But remember, open the dictionary in AppleScript editor, because that's where you find what each app implements and exposes to the system!

You can send Apple Events from JavaScript with JavaScriptOSA. However I'd recommend you investigate appscript (Python, Ruby) instead as it's more up-to-date and supported.

Related

Multilingual mobile app using AccessibilityIDs for Appium - bad recipe

My team supports a mobile app that is offered in several languages. I asked the team to implement AccessibilityIDs so that I can run Appium tests, which they did. (Why did I ask this? Because everyone in Appium testing is conveying that this is the best approach.)
Later - testing of the app's real world accessibility (using assistive technology - aka talkback or screenreader) revealed that using contextual information is desired. For example, if a button has text "Submit your order" ideally the Accessibility ID should be "Submit your order" not something like "form_page_submit_button"
The team brainstormed and the solution was to create a lang file for an obscure language that we don't plan to support. We settled on "pt-PT" so all the elements could have an accessibility ID that was not likely to change for some time.
This is now becoming a problem as I would like to have visual automated tests in English and French, not just Portuguese, and I am hoping to not have to maintain xpaths with ORs in it. For example, //*[contains(text(),'Submit') or contains(text(),'Soumettre')] ie, English and French.
In light of the fact that my app needs to be accessible to users more than it needs to be accessible for test script, I am evaluating which element selector strategy to recommend going forward. I am prepared to recommend using ID or name to alleviate this issue, but would like to get more thoughts on what others are doing in this space.
Going with ID's and names sort out the situation as mentioned in this answer.
If you like to use the XPath then you can use a dictionary variable to store the text based on the region i.e. [EN='Submit', FR='Soumettre'] and set the locators with the text-based on the region by using the dictionary values using the region as key and appending the text to the locator i.e. framing the locator dynamically based on the region might work out.
As I worked on Robot framework, using some piece of code to depict it and using collections and string library of robot framework
*** Variables ***
${region} EN #set this var as per region
${loc} xpath = //*[contains(text(),'replace_text')
&{submit_loc_text} EN=Submit
... FR=Soumettre
*** Keywords ***
implementation
${text_asper_region} Get From Dictionary ${submit_loc_text} ${region}
${loc} Replace String ${loc} replace_text ${text_asper_region}
Set Test Variable ${loc} ${loc}
If you still prefer to use accessibility ids and support all languages, I would suggest to create interface for every language to get the relevant accessibility locators. This will be easy to understand and maintain ofcourse efforts will be little more but I think it will be worth.

How to manipulate "data" objects in AppleScript

I'm working with iTunes via AppleScript. The artwork element of a track contains image data (or raw data, which appears in practice to return the same thing), which can be retrieved and, say, directly written to a file. (It's an e.g. PNG bytestream.)
But I don't know how to do anything with this thing besides write it to a file. I'd like to ask it how many bytes it contains, or even rummage through it (though the latter may well be out of scope for AppleScript). In Script Debugger, it looks like «data tdtaXXXXXX.....» (hex values where I wrote the XXXs), and the iTunes scripting dictionary doesn't link through to any useful type/class for it.
I'm not really sure what the guillemets mean in AppleScript, or what the nature of this object is, or whether this thing can be interrogated natively. Any references on this would be helpful. Thanks!
See https://books.google.com/books?id=rW5k0w_wC3MC&pg=PA57&lpg=PA57&dq=guillemets+applescript+events+data&source=bl&ots=ogzi9W4jxW&sig=7ct-n0wpzdhBhtHDJtTrZDKgEEk&hl=en&sa=X&ei=-qSYVICZAsjooASo0oKwCg&ved=0CB4Q6AEwAA#v=onepage&q=guillemets%20applescript%20events%20data&f=false for explanation of raw codes and data and use of guillemets in AppleScript; See this answer:
Getting artwork from current track in Applescript
for an example of writing image data from iTunes artwork to file.

How do I reverse engineer Mac OS X language localisation files for natural language learning?

OK, the goal of this question is not strictly programming related but it is a question programmers can answer using programming tools, and programmers may find useful answers here. Bear with me.
I find changing the system language in Mac OS X a useful way to augment my learning of natural languages, eg French. However sometimes I find a menu item or dialog box in French that I can't understand and it's a bore to google the translation or change the system language back to English. But I know that the English translation is hidden away somewhere in the localisation file and maps somehow to the French phrase. So what I want to do is extract all the text from all the localisation files to develop a mapping of this phrase in English = that phrase in French so I can look it up easily.
I know that the localisation files are stored in something like Localizable.strings, lproj files and nib files but I can't make head or tail of how they are stored or how to work with them. I can program but I've never written anything in Xcode. All the information I can find is for Mac OS / iOS programmers to localise their software, not for hackers to extract already made localisation information.
How can I extract the foreign language information as plain text from Mac OS X system and 3rd party software localisation files? Thanks!
Strings files are easy. They're simply dictionaries serialized as property lists. The dictionary keys are used by the program to look up the given string for a particular localization. You can build a mapping from English to another language by loading both dictionaries, iterating over the keys, and using the value from the English dictionary as the key in your output and the value from the other language dictionary as the value in your output.
NIBs are harder. The build process "compiles" NIB files in to a form that's not conduicive to editing or parsing. If you have access to uncompiled NIB files then you can use ibtool --export-strings-file to dump a strings file, which you could then process as per above. If you don't then I think you may have a hard time.

Translate Applescrip [key code 125 using command down] to appscript

how to translate the following Applescript to appscript:
tell application "System Events"
key code 0 using command down
end tell
I want to perform "Command + A"-like short cut, i.e., select all texts.
Look at the application ASTranslate which was installed as part of Appscript. It translates Applescript to Appscript for Python or Ruby. Be aware it just traps Apple Events and thus won't translate Applescript structures like loops or the like. It's very easy to use. Just past your Applescript in one pane, hit cmd-R, and it'll generate the translated Appscript + Python code. For your example it is
app(u'System Events').key_code(0, using=k.command_down)
While occasionally you'll find something that won't work quite right in general ASTranslate is an essential tool for using Appscript.
Bellow is the usage of keystroke of Applescript via Python, which is hard to search:
http://www.agapow.net/programming/python/applescript-via-python

General Purpose Filter As You Type (aka typeahead, Incremental find, autocomplete) is it out there?

Background
Lately I've become a fanatic that everything I type while working on a computer should be compatible with "DRY". If there's anything I have to type more than once in any context, I want some kind of user-aware auto-complete option to do some of the work for me -- always -- no exceptions.
Having to work under Windows, I've looked at GUI solutions to make this insane goal a reality.
The (almost) optimal solution
If you have a moment, open up Firefox 3.0 and type a few keystrokes into the address bar. You will notice that it performs a kind of Incremental Autocomplete based on space-separated sub-strings of whatever you type. Another place in Firefox that does something similar is the about:config URL.
This is sub-optimal, because I don't want this in Firefox only. I want to use this everywhere.
The Question
Does anyone out there know of a widget or app that does nothing but insanely good incremental auto-complete that can be used as a general purpose "run everywhere" tool? Something that allows the user to: 1) maintain one or more "completion candidate files"; 2) pick one of those files as the source for Firefox 3.0 style completion; 3) return the result (or blank if the user canceled), and do those three things only?
Details
Here's how it should work:
STEP1: user saves or more csv file(s) (or other easy-edit format) somewhere in his hard-drive
STEP2: user creates a Windows Script Host script or a batch file (or whatever) instantiates the FilterAsYouType GUI
STEP3: user runs the script file, and the script file instantiates the GUI, telling it which CSV file to use as the source of all potential completions
STEP4: the user either chooses one of the completions, supplies his own text that is not in the list, or cancels out without supplying anything
STEP5: when the user is done the script saves the result to a variable and does something with it
Here is some pseudo-code for the script:
include "GenericTypeaheadWidget";
var gengui = new GenericTypaheadWidget('c:\docs\favorite_foods.csv');
var fave_food = gengui.get_user_input();
if(fave_food != ''){
alert('you chose '+fave_food+'!');
}
The rationale
The goal is to just have a way to always be able to do auto-completions from a list of arbitrary items, even if the list is a couple thousand items, and not have to rely on it being built into some IDE or standalone application that only accepts certain kinds of input or has an overly-complicated API relative to the simplicity of this task.
CSV (or text or sqlite database) would provide a way for me to self-generate "candidate lists" or "history logs" and then just use those logs as the source of the possible completions.
The disclaimer
I've tried several GUI "launcher" programs, command-line engines like power-shell and scripting shells, the regular plain old command-line history with varying degrees of satisfaction. The problem with these is they all do extra superfluous stuff like searching directories or built-in commands. I just want nothing but whatever is in the CSV file I happen to be pointing at.
I'm wondering if there is any simple tool that does nothing but what I'm describing above.
UPDATE: It looks like this question is very closely related to Graphical Command Shell, which captures the essential idea presented here.
You should really try Launchy - it's exactly what you're looking for, a "run anything" with intelligent autocompletion. It completely changes the way you interact with a Windows PC.
And it has open source-code, so you can borrow its autocompletion code if you want to roll your own interface.

Resources