Wednesday, February 29, 2012

Install PHP PEAR on Windows 7

This seems like it should be obvious but it turns out getting PEAR isn't straight forward.  The documentation at pear.php.net is inaccurate for a windows install where you use the installer at php.iis.net to install PHP on IIS7. It turns out there is no go-pear.bat file in your php directory after installing this way.  However, after some trial and error and a bit of luck I figured out this seven steps to getting PEAR installed.

  1. Download go-pear.phar at http://pear.php.net/go-pear.phar
  2. put that file in your php home directory.
  3. open a command window as administrator; move to your php home directory
  4. enter "php go-pear.phar" without quotes
  5. accept the default value for everything it asks about; system wide, path options, updating your php.ini etc
  6. once the script is done pear is installed; you just have one last step
  7. in windows explorer go to your php home directory and double click on PEAR_ENV.reg to update your registry


PHP array_map in practice

Last week I spent some time making sure I understood how map and reduce actually work and what their purposes are.  This week I needed to use map while fixing a silly problem.  Some of this background info will be pure cruft to most of you but hopefully it will be enlightening in it's own way.

There is an application somewhere in our organization that utilizes an access database to store a catalog of information.  This catalog is then made available for consumption within our web properties via a webservice that is written in php and which returns the data contained within the database in either json or xml format.

Here is the basic way the json was being generated previously:

 $rs=odbc_exec($conn,$sql);

 //declare an array to hold the query results
 $data = array();
 
 //populate the jobs array with the query result set
 while($curRow = odbc_fetch_array($rs)){
  $data[] = $curRow;
 } 
 echo json_encode(array('jobs'=>$jobs));
Very straight forward and, it appeared to work well until today. Someone copied and pasted a descriptive field of one of the catalog items from a word document into the access database and a single smart quote (apostrophe really) worked its way into the data. When this happened that field was rendered in the json as null even though there was clearly data contained within.
It took me a little while to see that it was a smart quote buried in the middle of the paragraph of text but once I did I knew right away how to clean it out - using MAP; or in php paralance, array_map. Combined with this nice function to convert smart quotes I had a winning solution on my hand without having to add much code at all. Here is the final version of that same code:
 $rs=odbc_exec($conn,$sql);

 //declare an array to hold the query results
 $data = array();
 
 //populate the jobs array with the query result set
 while($curRow = odbc_fetch_array($rs)){
  $data[] = array_map("convert_smart_quotes",$curRow);
 } 
 echo json_encode(array('jobs'=>$jobs));
Just updating that one line in the middle of my while loop let me make sure that every element in every row was clean of nasty smart quotes by telling array_map to call the convert_smart_quotes function on each element. I have to say I really do like the power and simplicity of map (and reduce).

Monday, February 27, 2012

Rollback from Mountain Lion to Lion

Disclaimer: Before you do this; if it doesn't work you can't blame me.  It worked OK for me but maybe I was just lucky.

Ok, with that out of the way here's the lowdown.  I installed the developer preview of Mac OS X Mountain Lion and immediately started to notice some things that I really needed wouldn't work anymore.  No parallels, macports had issues and couldn't compile things with XCode 4.4 (what is required for Mt Lion), and quite a bit more dealing with things that depended on macports or the compiler within xcode.

So what did I do?  I tried to be creative and everything failed.

Oh, and I didn't have a time machine snapshot of my system before the upgrade.   Anyway, I eventually went to google to find some solutions and found this posting explaining how to install uninstall Mountain Lion except it doesn't show you how to uninstall Mountain Lion at all; it just shows you how to install Lion on another partition.  It does, however, have the key to the castle so to speak and I'll get into that in a little bit.

Before you can install Lion you need a copy of Lion.  Makes sense right?  Well I didn't have a copy but the aforementioned post told me I could get it using my apple dev center account but then it said I couldn't because I was running mountain lion and that I'd need to get it another way.  Well damn.

Later in the article he said you have to fool the system to let you install lion on the other partition by changing the version number of Mountain Lion.  I thought, well, what if I just do that now so I can get a copy of Lion and BAM! it worked.  So here are the basic steps.

  1.  I use sublime as my text editor and I have a command alias to launch sublime using the word sublime from the terminal..
    $ sublime /System/Library/CoreServices/SystemVersion.plist
  2. It will ask you for your password; enter it then change the two version instances from 10.8 to 10.7
  3. Save the file; you'll be asked for your password again; enter it.
  4. Now download Lion.  If you don't have an dev center account I guess you can pay the $30.
  5. wait a while.  Lion is big and it takes a long time to download.  It kind of freaked me out because it showed it going into my "Applications" at first but then it felt like nothing was happening.  Have some patience; go read reddit for a while.
  6. Eventually the download will finish and the Lion installer will open automatically.  Notice, nowhere in this list did I tell you to make a new partition.  Screw that step!
  7. Install right over mountain lion.  Just pick the partition you normally have things on and GO.
  8. WAIT WAIT.. finish reading this before you go...IT'S REALLY IMPORTANT
  9. When the install is done your machine will reboot and prompt you to login but you won't be able to.  Lion hates your old passwords and gets rid of them all - you can't login yet.  Just reboot again and wait for the screen to go completely black then hold down  cmd+r 
  10. HOLD THEM DOWN; don't just press and release.  HOLD THEM BOTH until a window opens called "Utilities"
  11. In the main menu bar there is a services option, click on it and find terminal.  If it isn't services just look in each menu until you find terminal; open terminal
  12. in the terminal window type "resetpassword" without the quotes and hit enter
  13. A new windows opens and it shows you all of your old accounts.  Find yours and reset your password.
  14. While you're at it reset the administrator password.
  15. Once your down with that close all the windows then in the system menu pick restart
  16. This time you don't have to hold down any keys.
  17. Eventually the login screen will pop up; login as yourself
  18. Now go to the system menu and install any updates so you're nice and secure.
That worked for me (I also reinstalled xcode 4.3 from the app store after that).

Good luck

-------
Some additional notes:

  1. After you re-install XCode 4.3; go to preferences, downloads, and install the command line tools
  2. I also reinstalled macports to be on the safe side
  3. parallels still doesn't work for me after the rollback.. I will reinstall parallels and hope for the best UPDATE: uninstall and reinstall fixed it.
  4. because of some changes to mail; rolling back left me with a broken mail app; not a deal breaker as I can just use outlook as we get our mail from an exchange server at the office.
  5. UPDATE: you can't use the systems preferences panel for setting desktop backgrounds after doing this.  You can still set your primary monitor background using the "right click, services menu" on the image you wan to make your wallpaper.

Thursday, February 09, 2012

Handbrake, Applescript, Automator, and iTunes Together as a Folder Action

Yesterday I posted about my initial attempt at automatically converting .avi files with handbrake to m4v files and having them automatically added to iTunes.  That plan worked fine if the items dropped into my watched folder were all of the type .avi AND they weren't in a subdirectory.

Tonight I decided to try and address these two deficincies.  First I can now handle the case where a folder is the "input" parameter; though my knowledge of applescript is so deficient I can only deal with one layer of directory heirarchy - sorry, no recursion.  I also now test for the extension of the file being processed to make sure it is an .avi before proceeding (otherwise I just skip the file).

Yesterday I also made the script look a little more generic by hiding some of the elements of my directory structure by using words like "me" - today I decided to just post it as I wrote it.  You will have to change some variable values to make this work on your system.


on run {input, parameters}
 repeat with x in input

  -- need to determine if input is a file or a directory..
  set details to (info for x without size)
  set allFiles to {}

  if kind of details is "folder" then
   -- if it is a folder, we need to grab all the contents as a list
   set tempFiles to list folder (x) without invisibles
   repeat with y in tempFiles
    set the end of allFiles to ((x as string) & y) as alias
   end repeat
  else
   -- if it is a file then we make a one item list..
   set the end of allFiles to x as alias
  end if
  
  -- now loop over the list we just made.
  repeat with i in allFiles
   
   -- only process avi files.
   if name extension of (info for i) is "avi" then
    try
     set text item delimiters to ":"
     set file_name to last text item of (i as text)
     set text item delimiters to ""
    on error
     set text item delimiters to ""
    end try
    
    set origFilepath to quoted form of POSIX path of (i as alias)
    set newFileName to "" & (characters 1 thru -5 of file_name as string) & ".m4v"
    set newFilepath to "/Users/bill/temp_movies/mp4/" & newFileName & ""
    
    
    --apple uses colons as delimiters while the  Untitled=drive; Users=directory; me=username; mp4=temp directory..
    set finalPath to ("Untitled:Users:bill:temp_movies:mp4:" & newFileName)
    
    
    --start the conversion; shell command uses the forward slash as the delimiter; hence two finalpath defined.
    set shellCommand to "nice /Applications/HandBrakeCLI -i " & origFilepath & " -o " & newFilepath & " --preset=\"AppleTV 2\";"
    do shell script shellCommand
    
    --I've told itunes to copy files on import; this way I don't have m4v's laying all over the place
    tell application "iTunes"
     add finalPath
    end tell
    
    --after the import is done I delete the m4v file I just created (from the temp directory)
    tell application "Finder"
     delete finalPath
    end tell
    
    -- prepare the movie for later deletion..
    set trashPath to "Untitled:Users:bill:temp_movies:to_trash:"
    tell application "Finder"
     move i to folder trashPath
    end tell
   end if
  end repeat
 end repeat
 return input
end run

Wednesday, February 08, 2012

Automatically convert .avi to .m4v and add to iTunes using Automator

That is a long title but not nearly as long and arduous as my process of figuring out how to do what it says.  Here is the scenario...

Let's say you and your mom are sharing a dropbox folder and she plops in an .avi of her recent performance in the community theater where she lives.  You don't really like the avi format and would prefer it in the m4v format and inside iTunes so you can watch it on your TV using your apple tv.  What is one way to do that?

Well, I'm going to tell you.  Now, trust me, this probably isn't the best way; but it works and that's all I wanted.  Initially I tried the export movies task in automator but the resultant video wasn't working in iTunes - I'm not sure why.  Therefore I resulted to using the Handbrake CLI from within an apple script via automator.  Here is the script:


on run {input, parameters}
 repeat with i in input
  try
   set text item delimiters to ":"
   set file_name to last text item of (i as text)
   set text item delimiters to ""
  on error
   set text item delimiters to ""
  end try
  
  set origFilepath to quoted form of POSIX path of (i as alias)
  set newFileName to "" & (characters 1 thru -5 of file_name as string) & ".m4v"
  set newFilepath to "/Users/me/mp4/" & newFileName & ""
  

  --apple uses colons as delimiters while the  Untitled=drive; Users=directory; me=username; mp4=temp directory..
  set finalPath to ("Untitled:Users:me:mp4:" & newFileName)
  
  
  --start the conversion; shell command uses the forward slash as the delimiter; hence two finalpath defined.
  set shellCommand to "nice /Applications/HandBrakeCLI -i " & origFilepath & " -o " & newFilepath & " --preset=\"AppleTV 2\";"
  do shell script shellCommand
  
  --I've told itunes to copy files on import; this way I don't have m4v's laying all over the place
  tell application "iTunes"
   add finalPath
  end tell
  
  --after the import is done I delete the m4v file I just created (from the temp directory)
  tell application "Finder"
   delete finalPath
  end tell
  
 end repeat
 
 return input
end run

Basically to use this you create a new automator "Folder Action" using an "Apple Script" paste this entire thing into the script (replacing anything apple puts there by default). Then pick the folder you want to watch. I noticed that the task usually fires off about 10 seconds after an .avi file shows up in the directory.

This still needs something to confirm the file that just plopped into the watch directory is an actual .avi file.  I didn't worry about that though it is probably  not too hard to add that check (though with apple script and its' crazy syntax I wouldn't bet on it).

Tuesday, February 07, 2012

2 Months of Mac : The Good and the Bad

I started using a mac two months ago after over twenty years of windows use.   However, rather than reiterate my opinion on both of my blogs (personal and technical) I've posted the full story over on my personal blog and I'm just putting a link to it here:

http://blog.rawlinson.us/two-months-with-a-mac-the-good-and-the-bad

I don't like cross linking like this but I hope you'll understand that this is a topic that might be interesting to both my technical friends/followers and my non-technical friends/family.  I hope you'll click through and read it and, maybe even comment with some helpful tips and tricks.