Can I use Applescript to find the current iTunes media location and other iTunes options - macos

Can I use Applescript to find the current iTunes media location and other iTunes options.There doesnt seem to be such options when I read the iTunes Applescript Dictionary within Script Editor but surely there is a way to do it.
I read in the past that something is stored in com.itunes.plist but its not plaintext and my plist file did not change when I created a new libary so Im not convinced it is still used, or if it is kept up to date.

Yes, #PaulTaylor, you can get the media folder location of the current user in AppleScript using the Apple-provided ​iTunes​Library framework. (documentation at iTunesLibrary at Apple)
Here's a working AppleScript to do it:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "iTunesLibrary"
set lib to current application's ITLibrary's libraryWithAPIVersion:"1.0" |error|:(missing value)
set mediaFolderPath to POSIX path of (lib's mediaFolderLocation as alias)
--> "/Volumes/LaCie 6/iTunes Library/"

The media location is not saved in the global iTunes preference file. Because you can have multiple libraries, and each library defines its own media location, this is actually saved in the the library preferences. The default library is located at ~/Music/iTunes/iTunes Library.itl. I'm not sure what kind of file this is. It does not seem to be a plist/xml file, nor an sqlite file. It seems to just be a proprietary binary file.
Inside the same folder, I also found iTunes Music Library.xml (after some testing around, that file is now missing, so YMMV for the rest of this explanation). Here is a truncated example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Major Version</key><integer>1</integer>
<key>Minor Version</key><integer>1</integer>
<key>Application Version</key><string>12.3.3.17</string>
<key>Date</key><date>2016-04-14T19:35:27Z</date>
<key>Features</key><integer>5</integer>
<key>Show Content Ratings</key><true/>
<key>Library Persistent ID</key><string>1AEAB6C2057C2167</string>
<key>Tracks</key>
<dict>
</dict>
<key>Playlists</key>
<array>
</array>
<key>Music Folder</key><string>file:///Users/<username>/Music/iTunes/iTunes%20Media/</string>
</dict>
</plist>
Note the key Music Folder. This is the setting you are looking for to find the library's media location. There are also some library settings, such as a list of playlists and track information.

Related

How do I debug an app on the Mac that accesses the camera?

My Qt C++ app captures video from the camera on the Mac. It has the NSCameraUsageDescription value set in its plist file. But, not surprisingly, this doesn't help if I am running it using lldb, either from the commandline or from Qt Creator. It just crashes with the line:
2020-02-28 15:32:14.462735-0500 mqtt[47726:867880] [access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data.
So how do I do that for lldb? It is in Qt Creator's Info.plist but I guess that doesn't help if it is running via lldb.
To allow your application to access the camera, you should have a Info.plist file with the field NSCameraUsageDescription filled with something.
If you're not building an application bundle (.app), then you can put the Info.plist next to your executable.
Then the next time you run it with lldb it will ask for authorization to access the camera.
Once you give it once, you might have to close the application and start it again.
According to my test, the following Info.plist content is enough :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSCameraUsageDescription</key>
<string>Video Input</string>
</dict>
</plist>
Since macOS Monterey (maybe also earlier versions) the app no longer crashes when the Info.plist is adjusted, but unfortunately it also does NOT show a camera image. Instead the view only shows a black screen.
It looks like macOS only allows access to the camera from applications that are located in the /Application directory.
Workaround to debug the application:
move your application bundle generated by QtCreator into the /Application directory (the generated *.app file).
create a symbolic link from the /Application/*.app directory to the build directory (ln -s /Application/MyFancyApp.app <MyFancyBuildDir>/)
Now you can launch and debug the app as usual using the Qt Creator.

Why doesn't sandboxing stop my app from accessing arbitrary URLs?

My understanding is that a sandboxed app is disallowed from accessing arbitrary URLs not chosen by the user. Why, then, is my simple test app able to:
NSWorkspace.shared.open(URL(fileURLWithPath: "/Library/Application Support/App Store/adoption.plist"))
Debug and Release builds both work, with no Console messages. My entitlements file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>
I must be misunderstanding something. Are a developer's apps unchecked on the development Mac? If so, how can I test that my app doesn't contain violations?
By using NSWorkspace you're not actually opening the file. Your app does not have access to the contents of that file.
You're just instructing the system to open that file with whatever is the default application that handles it. This is perfectly legal for sandboxed apps.
Try opening using NSFileHandle for example, and you should see an error.

Launch Mac app on OS load won't work

I am trying to create a plist file, to put within the LaunchAgents of the users Mac. This plist I will use to make sure it opens a specific application every time the Mac turns on or the user logs in. To my knowledge I am pretty sure the plist should work as it is right now, but it doesn't. Whenever I restart my Mac or log out and log in again, nothing happens.
To make it slightly easier to compare with other Mac's, I am trying to open the regular Calculator app, of which is on all Mac's.
To list what I have currently done is, make the plist below and named it open.plist Along with that I have placed it in the LaunchAgents folder, which is within the library folder of my Mac.
Here is the current plist of mine.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.user.loginscript</string>
<key>Program</key>
<string>/Applications/Calculator.app</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Basically the idea is to have this plist within the LaunhAgents and then have it load an app within the Application or Documents folder.
LaunchAgents should only be used for background services. It isn't an appropriate way to launch applications at login.
To launch an application at login, add it as a login item. Login items can also be added manually using the "Users & Groups" system preference pane.

How to create snippet subfolders in textmate bundle

I've just discovered textmate and I love it. I would love to use it as a way of storing my own snippets. I know how to do this in textmate but as I want to add loads of snippets I don't want them to become disorganised. I would like to add them into organised subfolders under the relevant bundle. eg under the shell script bundle I would like to add a folder that keeps all my networking snippets together. I cant find anywhere how to do this but I know it can be done as some bundles are organised like this.....Help
I managed to figure this out with a lot of trial and error and starting with this Superuser answer.
The only way to do it in TextMate 2.0 is to manually edit the info.plist file for your bundle. I suggest doing this on an exported copy of the bundle and reloading it into textmate. To export a bundle right click on the bundle in bundle editor and click Export Bundle....
Start by adding a mainMenu section at the top level of the plist file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
<key>mainMenu</key>
<dict>
</dict>
</dict>
</plist>
From what I can tell, the mainMenu dict supports 3 keys: excludedItems, items, and submenus. The excludedItems and items are arrays containing a list of UUIDs of either bundle items (snippets, commands, etc.) or submenus. You can get the UUID of a command or snippet by opening it in textmate and finding the uuid key; it'll look like:
<key>uuid</key>
<string>0A2DB1AC-3049-4BD5-8931-641E716990F9</string>
Once you have the UUIDs of your items you can list them in items to populate the bundle menu in the order you wish, e.g.:
<key>items</key>
<array>
<string>409b0e74-9ab5-4d35-b957-9ddf23a71c0c</string>
<string>------------------------------------</string>
<string>d2c991dc-a00e-4247-8479-f2d29f387319</string>
</array>
If you use a series of - characters in lieu of a UUID, it will create a separator in the menu. Likewise, if there are snippets you don't want to display in the bundle's menu you can add them to excludedItems.
To create submenus you have to define them inside submenus, like so:
<key>submenus</key>
<dict>
<key>71BE58B2-E486-4B21-93F1-C208D4914099</key>
<dict>
<key>items</key>
<array>
<string>6D0B2B9D-62C7-4842-BA28-F3379E887D93</string>
<string>CADC55BD-0D0A-48C8-B296-35FA7AAE09CA</string>
</array>
<key>name</key>
<string>C++ Snippets</string>
</dict>
</dict>
Each submenu needs to have an associated UUID inside <key>...</key>. I created one from an online UUID generator. You can then add the submenu's UUID to the top-level items array to add the submenu to your bundle's menu.
Finally, when loading your bundle into textmate you must first delete all cached instances of the bundle from:
~/Library/Application Support/Avian/Bundles
~/Library/Application Support/Avian/Pristine Copy/Bundles
If you don't, textmate will sometimes ignore the newly loaded bundle. Not sure if there's a cleaner way to reload a bundle, but deleting it worked for me.
For a complete example see this commit in the ROS bundle on my Github.
Just some extra info on the excellent answer above
As of TM2 rc23, you can access the UUID of an existing item by right-clicking on it in the bundle editor window (accessed with cntrl-option-command-B)
You can create a UUID in terminal.app with the command uuidgen (you could also make this into a command if you use this often)
TM2 doesn't need the cache clearing - it watches for changes in the plist.
#user96157 is clear about this, but note you have to also add your new submenu to the mainMenu. So:
<key>mainMenu</key>
<dict>
<key>items</key>
<array>
<string>COPY-UUID-FOR-YOUR-NEW-SUB-MENU-HERE!</string>

Access sidecar files in a Mac sandboxed app

I need to access sidecar XMP files in a document-based photo editor application.
The image files are the documents, and I need to access the sidecar XMP file when the user open and save an image document.
Is it possible to access sidecar files (such as XMP) in a sandboxed document-based application?
I understand that it's not possible by default, but what is the minimal temporary security exception that is needed to allow that?
Is there a workaround for this without using temporary exception?
Note that it's impossible to guarantee the the image files document-scoped bookmarks to the side-cars (as they might created by other apps on different platforms), so this solution won't work.
While this question is old I thought I would share my solution. You can add an entry to your CFBundleDocumentTypes section in your apps info.plist with the NSIsRelatedItemType set to true. Then your sandboxed app will be able to open any file the user gives permission to with the same name but has the extensions that you list. Here is an example for an xmp sidecar file:
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>xmp</string>
</array>
<key>CFBundleTypeName</key>
<string>XMP sidecar</string>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>NSIsRelatedItemType</key>
<true/>
</dict>
</array>

Resources