Apple Logo Itsamac Hosting
Mac OS Journal
EditorialsColumnsFeaturesReviewsArchives/StaffSubscribe
 
Table of Contents From the Desktop Connect Feature Column The CoXFiles The Gaming Landscape Warehouse The Surf Report Simply Web
The Database Guru The AppleScript Foundry Mac Mastery Review - Eyecandy 4000 Review - Risk II Review - Wheel of Fortune Review - Mac Fun Pack 2 Behind the Scenes    
   
 
Itsamac.com
Red Light Runner
Applelust.com
     
 

The AppleScript Foundry
February 2001 || Volume 01, Issue 07

Taming Napster File Downloads

As a Mac user, I don't ordinarily run into areas where I feel Windows users have an advantage. Back when the Mac was created, PCs running DOS were limited to eight character file names with a three character file extension. The Mac supported (and still does) 31 character file names as
well as 4-letter character file types and creator types.

But when Windows 95 debuted, it supported 255 character file names! Now, I happen to think that 255 characters is much more than the average user needs, and they don't make for very neat file lists. But one area where they DO come in handy is when you are dealing with MP3 files.

For those who don't know what MP3 is, it's a compressed sound format that grew out of the MPEG (Motion Picture Enhancement Group) standard for encoding video and audio tracks [Editor's Note: For more information, read this issue's Warehouse.]. MP3 compresses sound by stripping out frequencies that the human ear cannot hear and compressing the rest much the same way that StuffIt compresses document files.

For those familiar with MP3, it is not news that Napster, the online peer-to-peer music or MP3 sharing service, now has an official Macintosh client program. Mac users can now participate in the online music revolution with most of the functionality that Windows users have enjoyed.

The problem is, most of Napster's users are also Windows users, who have a tendency to name their files with long concatenations of the artist's name, the album name, the number of the song as it appears on the album, and the song title. And to top things off, they tack ".mp3" to the end!

As you might guess, this makes for some hideously long file names, and most of my Napster downloaded files end up truncated before they get to a unique name. Just downloading files from the same artist and album will max out the 31 character limit long before you get to the song's title. The result is that you risk getting files whose name consists of just the artist and some of the title, followed by a number (to make it unique) and the obligatory ".mp3" file extension.

However, the Mac Napster client software does help you by sticking the entire file name in the file's comment entry (in the Get Info box). So if you set your Finder preferences for your download folder to show comments, you can at least tell the files apart.

AppleScript, a Whip, and a Chair

It further occurred to me that when other users were trying to browse my files through Napster, they couldn't tell what the heck I had because the file names were so messed up. At that point, I turned to AppleScript for help.

First, I realized that I could set the comment field to reflect the complete name, then write a script to snag the first 27 characters of the comment, then tack on the ".mp3" extension for Windows users.

Second, being limited to short file names, I realized that the standard naming conventions of most Windows users for MP3 files had to go. Instead, I restructured the name to delete unnecessary characters like underscores, dashes, etc. and then inverted the order of the elements (from artist, album, track number, song title to track number, song title, artist, album). The reasoning was that Napster allows searching by artist and song title, so the least important information was the album name - if it was lost in the name folks could still find songs by artist and song title.

So I wanted to revamp the files' comment info and then take that info and rename the file. The Get Info box before running the script looks like this:

Here's the breakdown on the script. I reused some elements from previous scripts, like the routine to add the Windows file type based on the Macintosh file type, and another piece that strips out special characters (underscores, dashes, etc.).

Comments?

First, let's initialize some things to use later. If you want to replace special characters with some other character, set replace_char to the character you want to replace with and use_replace_char to true. Max_length is the maximum file name length (minus the 4 characters for the period and 3 letter file type). The special_character list represents the characters I don't want to appear in the final name. The last 2 lines will be explained later.

-- Set variables
set replace_char to "_"
set use_replace_char to false
set max_length to 27
set special_char to {"/", ";", "?", "*", "<", ">", "", "ƒ", "#", "!", "@", "&", "(", ")", "", "-", "_", "."}
set my_as_lib to (load script file "Detoo:Bin:My AS lib")
set ext_lib to (load script file "Artoo:System Folder:Scripts:Finder Scripts:Add Prefix/Suffix to Files")

Next, we tell the Finder to get the list of selected items and rename them to whatever is in the comment field. Because I launch my scripts using the OSA Menu extension, I don't need to do anything except select the files to rename and then launch the script. However, if you prefer to make your script a "droplet" you can do that by surrounding the tell block with an on open handler and saving the file as an application rather than as a compiled script. I won't go into that here, but instead we'll write a simple, compiled script for use with OSA Menu.

tell application "Finder"
  set the selected_items_list to every file of selection
  if the (number of items of the selected_items_list) is not 0 then
    repeat with my_item in the selection --step through the list
      --fetch the comment for the file
      copy (the comment of the information window of my_item) to my_comment
      --and make sure the comment isn't empty
      if the (number of characters of my_comment) is not 0 then
        -- step through the items
        set my_name to ""
        set my_index to 1
        set new_index to 1
        --repeat until we reach max_length or run out of characters
        repeat until the number of characters of my_name is max_length or my_index > ¬
          the number of characters of my_comment
          copy (character my_index of my_comment) to my_char
          --is it a special character?
          if my_char is not in special_char then
              --no, add it
              set my_name to my_name & my_char
              set new_index to new_index + 1
           else
              --yes, is use_replace_char true?
              if use_replace_char then
                set my_name to my_name
                set new_index to new_index + 1
              end if
           end if
          set my_index to my_index + 1
        end repeat
        --transfer the new name and add the Windows file type

        tell my_as_lib
          set pc_type to set_pc_type(my_item)
        end tell

        tell ext_lib
          set_item_name(my_item, my_name & pc_type)
        end tell
      else
        display dialog "File " & my_item & " has no comment to use for a file name."
      end if
    end repeat
  else
    display dialog "No items are selected."
  end if
end tell

We then finish the script with a couple of handlers. The first one tests the Mac file type and adds the Windows file type. I've stored frequently used handlers I have written in a file called, "My AS Lib." That file contains the handler:

on set_pc_type(this_file)
  set the mac_type to the file type of this_file
  set the pc_type to ".unk"
  if the mac_type is "EPSF" then set the pc_type to ".eps"
  if the mac_type is"TIFF" then set the pc_type to".tif"
  if the mac_type is"XDOC" then set the pc_type to".qxd"
  if the mac_type is"JPEG" then set the pc_type to".jpg"
  if the mac_type is"TEXT" then set the pc_type to".txt"
  if the mac_type is"PDF " then set the pc_type to".pdf"
  if the mac_type is"MP3 " then set the pc_type to".mp3"
  return pc_type
end set_pc_type

This script understands a small handful of Windows types, but you can extend the list to whatever types you may need to use if you are transferring files to/from a Windows machine.

Reusable Code Makes Your Life Easier

We preloaded the scripts containing the 2 handlers at the beginning of the script, using the lines:

set my_as_lib to (load script file "Detoo:Bin:My AS lib")
set ext_lib to (load script file "Artoo:System Folder:Scripts:Finder Scripts:Add Prefix/Suffix to Files")

Now we can call the handlers from those scripts using a simple tell block. Note that you don't need to specify the complete path (disk:folder:filename) as I did - if AppleScript can't find the file, it will ask you where it is located the first time the script is run.

The last handler was actually written by Sal Soghoian and is contained in his "Add Prefix/Suffix to Files" script. It handles duplicate file names by alerting the user that the name is already taken and allows the user to make changes to the proposed name or to skip the item entirely. Rather than clutter my script with a duplicate of his code, I've referenced it remotely using the of keyword, the same way I called on my own routine in "My AS Lib."

The code is ©1998 Sal Soghoian, Apple Computer:

on set_item_name(this_item, new_item_name)
  tell application "Finder"
    activate
    set the parent_container_path to (the container of this_item) as text
    if not (exists file (the parent_container_path & new_item_name)) then
      try
        set the name of this_item to new_item_name
      on error the error_message number the error_number
        if the error_number is -59 then
          set the error_message to "This name contains improper characters, such as a colon (:)."
        else --the suggested name is too long
          set the error_message to "The name is more than 31 characters long."
        end if
        beep
        display dialog the error_message default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
        copy the result as list to {new_item_name, button_pressed}
        if the button_pressed is "Skip" then return 0
        my set_item_name(this_item, new_item_name)
      end try
    else --the name already exists
      beep
      display dialog "This name is already taken, please rename." default answer new_item_name buttons {"Cancel", "Skip", "OK"} default button 3
      copy the result as list to {new_item_name, button_pressed}
      if the button_pressed is "Skip" then return 0
      my set_item_name(this_item, new_item_name)
    end if
  end tell
end set_item_name

Referencing external script handlers is tricky and not for everyone! But if you can master it, it allows you to reuse bits of code without retyping them (or cutting and pasting them) and it allows you upgrade all your scripts at the same time. For example, by adding to the list of Mac/Windows file types in my set_pc_type script, I automatically give every script that uses that routine the ability to recognize more file types!

However, if you have difficulty with it, you can always copy the above 2 handlers into your script, then change the line that references those handlers to:

my set_item_name(my_item, my_name & my set_pc_type(my_item))

My tells AppleScript to look for the handler contained somewhere within the current script, rather than sending the command to the application mentioned in the surrounding tell block. An alternative to my is to follow the reference with the words of me.

That's all for now!

Illustrator Scripting Redux

I received some mail regarding the Illustrator scripting column, and thought I'd share it with you, since it's the best explanation I have come across about some applications launching when you open their dictionary in Script Editor or SMILE.

Don Rossi wrote:

I wanted to comment on why Illustrator must be running to write a script. It is actually a good thing. By doing so, Adobe makes other plugins capable of handling Apple events if the authors choose to create a dictionary. It is really no different from Quark Xpress or Photoshop. To compile a script, Applescript must know what Xtensions or Plugins also provide dictionaries. So the App must be lauched. While it is annoying when you open a script, in the long run it is a good thing. I know I always have to repeat this over and over while Quark is launching and searching for illegal copies of itself :)

Thanks for your time and effort with your review.

Good explanation, Don. I hadn't realized that was the reason, but it makes sense. Quark always does the same thing to me. I still wish the AS dictionary was part of AI, though.

More About the AppleScript Foundry

Every month in the AppleScript Foundry, I'll be sharing what I know about scripting. Since the object of this column is to get people who are new to scripting up and running, I will take a hands on approach, explaining new terms along the way. However, it is not my goal to talk down to the reader - If you want harder stuff, just write me! You can reach me at kevin@macosjournal.com or you can use the handy web feedback form.

Here is a list of places you can go to get more info on AppleScript:

Kevin's Icon Kevin Bradley - kevin@macosjournal.com
Kevin's Page - Feedback Form

back Mac OS Journal forward
 
 
   
© 2000 - 2004, MacOSJournal.com. All rights reserved. No part of this publication may be reproduced in any way without prior, expressed permission from the Publisher. It is the sole property of MacOSJournal.com and its writers, who retain copyright to their own works. If you wish to link to us, please see our Privacy Statement for conditions. Apple, Macintosh, and Mac are trademarks of Apple Computer, Inc, with whom we are in no way affiliated or endorsed.
Hosting provided by itsamac.com -- Macintosh Powered Web Hosting
Serve Different