How To Find the Private Key For the Delicious API

I’d like to write a python script that looked at my Delicious Bookmarks and checks to see if they are dead links. This is possible because Delicious has an API. And you can just ask for what you want by asking for a specific URL.

That works fine as long as you don’t want your private bookmarks. If you want them, you have to:

{key} = a security key for the feed, which can be found via the page associated with the feed (eg. inbox, network or bookmarks). Allows visibilty to otherwise private data.

But there is no explanation of how you find the key. It says via the “page associated with the feed”. But it’s not. Not anymore, because Delicious changed its look and in the process hid its RSS feeds.

As an aside, when did RSS because pariah? Google drops Readers, Delicious hides its RSS feeds. What’s up?

But you can still find the needed private key by signing in to your account and going to http://feeds.delicious.com/{username}/

Over on the right side, you’ll see something like the image at the right: Delicious Sidebar

The URL for the “Private” link has your key in it.

You can get it by right clicking and using “Copy Link” or your browser’s equivalent. The private key is that big bunch of letters and numbers after the “?private=”. Just put it on your request URL the same way.

BTW: this key may change if you change your password.

iBooks GUID Problem When Duplicating iBooks Author Documents

norton to iabaMy wife embarked on creating a textbook for Major British Writers at Abilene Christian University last summer. In the process she ran into a problem after duplicating iBooks Author (IBA) files to break up the book. When her students attempted to download and install the books, they found they could only have one of them on their iPads at a time. I’m writing this post to document what causes this and how I fixed it.

A Short History of the Problem.

If you think about it this was a prime textbook to move to digital. Every student has had to buy the Norton Anthology, a massive 4 inch thick tome that contains works written hundreds of years ago and now in the public domain. So gathering these works into a digital format should almost eliminate the cost of the book, and save the student having to carry around this 10 lb book everywhere.

As she was working on it, after gathering many of the works, she felt the content was too long for just one iBook. She decided to break it into four books, broken down by the era of the works ie. Renaissance, Neoclassical, Old English, Middle English.

You would think this would be a simple process, but it isn’t. You can’t cut and paste entire pages and sections from one iBooks Author document to another. Even cutting and pasting individual parts doesn’t move all the data and template information.

Her solution was to duplicate her original document and then delete the parts she didn’t want for each book. This gave her all the template layout she’d done, and all the content she added and formatted.

The Symptoms

This seemed to work fine. She edited the now four books, published them directly from iBooks Author to her iPad with no problem. Then to distribute them to her class she exported .ibooks documents and put them on a server. The students connected directly from their iPads in Safari and downloaded them. She wasn’t distributing via iTunes yet because the books are still works in progress.

Then the problem showed up.

The students downloaded the first book fine, but when they attempted to add a second book, iBooks on their iPad told them that book was already installed on their iPad. It was seeing both books as the same, even though they had different titles and content.

She tried changing every setting she could find in iBooks Author but nothing mattered.

The Problem

After her description I started having an idea what the problem was. It seemed to me Apple was using something internal to the file to uniquely identify a book. Similar to what they do with applications, and I guessed it was the same kind of identifier.

I expected the iBooks files to actually be bundles like applications and many other document types are. But it turns out they aren’t. I’m still not actually sure what file type they are, but BBEdit knows. I dropped the IBA file on BBEdit, expecting to wade through the binary format to find the expected identifier. BBEdit displayed the file as a collection of subfiles. Most were media files – jpegs, pdfs, etc – for the things included in the book. But down in the middle of the list of files was one called “index.xml”.

Viewing index.xml, I found what I was looking for. A GUID tag with the recognizable 32 character string of numbers and letters. All four of her IBA files had the same GUID.

I also opened the .ibooks file and there were a couple of places this GUID number appeared, but I decided they weren’t the place to do the edits, because when she makes changes and generates a new .ibooks file, they would get blown away.

The Solution

Once I knew the problem the solution was pretty easy.

1. Generate a new GUID.

If you have the Xcode developer tools installed, open the terminal and type “uuidgen” and hit return. You’ll get a new UUID.

uuidgen terminal

2. Open your .iba file in BBEdit and find the index.xml file.
bbedit index ss
Once you select this file from the list, you will get 2 lines of XML displayed on the right. Turn on “Soft Wrap Text” so you can more easily see the XML.

3. Look for the XML tag with GUID in it.

There should be a line that looks something like this:

<sl:textbook sl:in-toc-upgraded=”true” sl:GUID=”A8C59273-86AC-43D7-BCE2-A6916B805302″>

4. Replace the GUID with your new one.

Do I really need to explain how to copy and paste?

Then save the file.

That’s it. Now your IBA file has a new non-duplicate GUID for the book. You can re-export to generate a new .ibooks file and there shouldn’t be a conflict.

Speaking of Simulators That Don’t Simulate.

One of my complaints about the Corona Simulator was that things don’t run at the same speed on the device and in the simulator. Generally they run faster in the Corona Simulator.

Well working with Cocos2d, I had written 2 lines of code and discovered things don’t run in the iOS simulator like the device. They run slower.

In Corona I do this:

-- display the background
background_image = display.newImage( "images/paper_bkg.png" )
group:insert( background_image )

And set the background to an image that looks like lined notebook paper – my app has a hand drawn metaphor.

In Cocos2d I did this:

CCSprite*   titleSprite = [CCSprite spriteWithFile:@"paper_bkg.png"];
float centerY = winSize.height - (titleSprite.contentSize.height/2);
float centerX = titleSprite.contentSize.width/2; // sqrt of 2
titleSprite.position = ccp( centerX, centerY);
[self addChild:titleSprite];

Run in the simulator and the FPS goes from 60 FPS to 15. Run it on the iPad and it goes back to 60 FPS.

Nothing Like Shit Not Working To Get You To Optimize

I looked around for the reason and found some posts about a background sprite being too big, and how you should break it up into smaller power of 2 parts and it will run faster. Tried that, but had problems getting the pieces to line up. And in the end you are still loading a really big image into memory to do this.

That’s when I learned my background image shouldn’t really be a PNG. Here’s why:

1. PNGs are always 32bit. Even if you take say a 16 bit image and save it as a PNG, it gets encoded 32bits per pixel.

2. You should use lower bit depth images if you can. iOS – welcome back to the good old days when memory mattered. Loading an 8bit retina resolution iPad image (2048×1536) is huge. Personally I can’t tell the difference between a scanned piece of notebook paper at 32bit color and 16bit color, but it will drop the file size in half.

3. There’s a special optimized image file format for iOS. Turns out the graphic chip in this iDevices has a format optimized for it – PVR – and it can be compressed. I’m using TexturePacker for my sprites and it will output a .pv.ccz file that should save memory and work better with the device’s graphic chips.

Corona SDK Game Project Post-mordem

This past semester I audited Intro to Digital Entertainment at ACU. I’ve always been interested in video game development and wanted to learn more.

For my final project I decided to write a video game using the cross-platform mobile SDK, Corona. That project was due last Thursday and I decided to post my thoughts on the framework I used.

The teacher of the class, Dr. Brian Burton, has written a book “Mobile App Development with Corona”. I decided I’d give it a try for my project because he’d given us a sample to start from and was so positive about it.

Well the project is done and at our presentation we got a lot of positive feedback about the game. I learned a lot doing the project, so here are my thoughts on developing with Corona.

Pros

You can get a lot done very easily. This is really one of Corona’s biggest pluses. Want to display a graphic on screen? One line of code.

background_image = display.newImage( "images/paper_bkg.png" )

Want sprite animation? One line of code.

ship.sp_ship = spriteSheet:grabSprite("ship.psd", true);

Want to move it from point A to point B?

transition.to(scene.ship,{ x=1000, y=1000, rotation=45, time=1000, onComplete=finishShipMove, transition=easing.outQuad })

Adding collision detection, gravity effects, and many other features are very easy to do. I gave my son access to Dr Burton’s book and my laptop one day during Thanksgiving and he had sprites flying around in no time. The goal of Corona’s founders is to make an environment for non-programmers to make games.

Aside: I think this goal is part of my frustration. I kept expecting things a professional programmer would want from an environment and language.

The Community is Helpful.

A couple of times I posted to the forums and someone always responded back quickly. The people who use Corona love it and want to help others. I expect this post will get comments from people at Corona Labs, because I’ve seen them do it for other posts about Corona.

Cons

Lua. You write all of your game code in the language Lua. When you are writing a cross platform framework, you have to pick a language to write in because the various platforms all use different ones. Android uses Java. iOS uses Objective-C. Corona uses Lua.

My understanding is the main reason for picking Lua is the interpreter only adds 500k to the executable, which is an important consideration when you must have your framework code and the interpreter in every app you make.

But frankly Lua sucks. I could really go on and on with details, but I’ll try and be succinct.

Lua has no object-orientedness, but it looks like it does. (I didn’t realize how dependent/addicted to OOP I was until I didn’t have it) In Lua just about everything is a table – what Objective-C calls a dictionary – a list of key value pairs. Even arrays are tables where the keys are the array indexes. The reason Lua look like it has objects is you can set function “pointers” as values, so to call a function on a table it looks like an object function call. See the display call above. But there are no constructors/destructors. You can’t just release and object and know it will get rid of all its data, you have to write not just the dealloc code, but the mechanism.

This also leads to very strange scoping of variables, which I still don’t fully understand. But all globals are really in a secret table called _G. You can add variables to an “object” just by assigning them – better not make a typo in an assignment. This can be useful, for instance the SDK uses this when turning display object into physics bodies. You pass it a display object and it adds all the variables and functions needed for collision detection to it.

But then in other instances you will pass an “object” into a function that calls back later but when you get the callback you no longer have all the parts you passed in. And there is a “self” variable, which I never figured out.

What this means is you really have to give up on encapsulation. Once you realize everything should just be a global, life in Corona gets much easier.

The Corona Toolset is Primitive. The other problem with Corona is it lacks the support tools to make easy to use. Really there are no tools from Corona itself. You edit text files in whatever editor you want, then launch the simulator and point it to your main.lua file. Then things run.

The Documentation if Weak. Corona staff have freely said their docs suck. I wouldn’t go that far. I never found any API there wasn’t at least a minimal explanation of. (Except a break down of what fields are available in config.lua) I remember times Apple’s own docs have been worse. But there isn’t much depth. Not enough explanation of why things work they way they do. Also the overview/tutorials are spread across their blog and only occasionally linked to from the relavent API pages.

There’s no IDE. There are some third party ones, but none as slick and complete as say XCode.

There’s no Debugger. Well there is a command line debugger, but it was easier just to debug via print() than to figure that out. It really, really needs a visual debugger.

The Simulator is only kind of a simulator. Seems to me the Simulator is a OpenGL-only window. Since Corona is mainly for games, most of what it does is in OpenGL. The Simulator just shows you this stuff. This becomes obvious when you want to do something like put up a native alert, or use the keyboard for input. Can’t be done in the simulator. There are also performance differences between OpenGL on your Mac in the simulator and on your iPhone/iPad, which it seems a simulator should simulate.

“But Ron, you can always use the iOS Simulator.” No, you can’t debug in the iOS Simulator. Which I discovered and panicked the first time something ran fine in the Simulator and hung in the iOS Simulator.

This is partially a function of Corna and partially an Apple problem. The Corona side is they have separated you from the actual OS – that’s the price you pay for cross platform – and therefore you don’t get the access that would allow you to use a real debugger.

The other is classic Apple. When iOS 6 came out, Apple decided to limit app’s ability to output to console. Specifically they didn’t want apps like Corona let the Lua scripts output to console. So in order to debug via print() I had to write an entire set of logging routines (kind of an object) that would log to a file instead of stdout. A royal pain, but not one I blame Corona Labs for.

I won’t complain about the fact if you want to build something to run in the iOS Simulator or your device, Corona requires a round trip via the Internet to do the compile and build, and that roundtrip is purposefully delayed by 20-30 seconds if you aren’t a paying member. That’s a valid shareware limitation.

I do wonder how many of these complaints would go away if the Corona SDK were a library you included in XCode and did your coding and debugging there. But that doesn’t really work for the cross-platform nature of the framework. Also it doesn’t appear XCode understands Lua, but hey maybe they could change to Python which would solve almost all my Lua problems. (Ahh Corona that I could program in Python, that gives me a warm fuzzy feeling just reading it.)

This has gone on long enough, but I knew it would be long. I’ve essentially worked full-time on this project for a month, so I’ve had time to build up some complaints.

The other possibility is I’m full of it, since I haven’t used other tools, maybe I don’t know how easy Corona is. I’ll know by the end of the year. I’m going to do is rewrite my game using Cocos2d and Chipmunk. There are two reasons for this.

Firstly I need an iOS app in the AppStore. I’ve been looking for a programming job and most people who are looking for iOS programmers want them to have an app in the store. Don’t know how well an interview would go if I said, “Well it’s in the store but I didn’t write it in Cocoa.”

Secondly, this will let me work where I’m comfortable. I’ve done MacOS programming for almost 20 years now. About 9 of those using OSX/Cocoa/Obective-C. I can apply those skills to to my game if I write it in a native format.

Scripting XCode4 To Generate Method Comments

This article will show you how to use a python script to generate a comment from the actual declaration of the method.

So you’d have something that looked like this (Click image at right for bigger)

XCode 4 Doesn’t Support Scripting of Any Kind

XCode 4 removed the Script Menu and all the hooks that used to be there. They don’t even let you use AppleEvents to set the selection. Read the How This Script Came To Be section of the post for more details.

What you have to do is create a Service that receives the selected text, pass it to your script as an argument, then takes your script’s output and replace the selected text with it.

I wrote a Service once a long time ago using XCode and Cocoa, but that’s really way more than we need to do. Instead we will us Automator to handle the Service part for us.

Create An Automator Service

1. Launch Automator.
I just hit Cmd-Space, and start typing till I see it. But it’s in the Application folder if you’d rather click to it.

2. Create A New Workflow.
Cmd-N, or File > New

3. Select “Service” from the Choose Type Panel

4. Find the Run Shell Script Action.
If the Library isn’t showing, click the button in the tool bar, or View > Show Library.
Then there is a little search field at the top, type in Run and you should see the action (like the image at the left).
Drag the Run Shell Script action to the right hand panel.

5. Configure the Run Shell Script Action.
The core the commenting work is the script. I’m specifically using it to make method comments, but you could write your own script to do anything. Brian wrote scripts that aligned selected routine names so the colons lined up vertically, that’s pretty cool. I’ve written scripts to take a list of serial numbers and format them as variable declarations to a pirate list. The sky is the limit.
Select /usr/bin/python form the Shell: popup. You could also write your script in a different language. If you do select a different shell from the popup.
Here’s the script I’m using for the commenting:
RoutineCommenter.py
I’ll talk about the details in a minute, but right now downloaded it, open it in a text editor like TextWrangler or even XCode, copy its content, and paste it into the Run Shell Script text area.

6. Save your Automator Workflow
Cmd-S, or File > Save. Instead of a standard save dialog, you get a little panel that says “Save service as:” and lets you enter the name you want to use. Pick carefully because this is what will be in the Services menu. And I couldn’t figure out how to change it later. Ended up duplicating the file just to change the name.
The Automator file is actually created in ~/Library/Services.

That’s it as far and hooking up the script. You can try it out by opening some code in XCode4, selecting a declaration in the code, and going to Apple > Services > Generate Method Comment, or whatever you named it.

A new comment will appear and you can even Shift Tab and get taken to the description bubble for editing.

You also can do this in most text editors, so even is you dont’ use XCode you can use the service.

How the Script Works

I won’t go into the details, because I think I did a pretty good job documenting it. Basically it just parses through the string, finds the parts it needs, and generates strings for the comment. It doesn’t really try to understand the code, it just gets what it needs to generate what I want for the comment.

You can go in and change the print statements in main() to reformat it to your comment style.

Debugging An Automator Shell Script Service

Editing and debugging a script in Automator is a pain in the ass, to the point it really isn’t viable . For one you can’t run the Service in XCode and get any feedback in Automator. What Automator will suggest if you click the run button, is you add a “Get Specific Text” action before and it’s output will be passed to your script. This “works”. You run and fail in Automator.

But you can’t read python error messages in the Automator Log window. You only get the first line of the error, which is bad because python outputs a traceback first, so every error is multiple lines long.

Here’s what I ended up doing.

Really you need to run it from the command line, and you need a real text editor, not just a text view. So I opened a new document in TextWrangler (for some reason it seems wrong to use XCode4). I pasted the code from my Automator action into the TextWrangler document and saved it as a .py file.

You’ve got my .py file to start with. You’ll need to change the name of the file you downloaded. I had to add .txt to the end for security reasons.

To run your script you are going to use python from the command line in Terminal. Find where you saved your script and cd there in terminal. Type “python RoutineCommenter.py” and you’ll get a wonderful error message because there is no text passed in to parse. No arguments at all.

You could add a string of a method declaration to your command line, but one thing you’ll want to test is how your script handles multi-line declarations.

Luckily I’ve given you a way in the code. Look at line 26-29:

TESTING = False

# for debugging here are some string to parse.
testString = “- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation”

And then at 102-103:

if TESTING: routineName = testString
else: routineName = sys.argv[1]

If you set TESTING to True, then instead of using a passed in argument from the command line, the code uses testString, which is defined on line 29. Make Testing True and go back and rerun your script. Now you will see a comment.

There are a few other bits of debugging code I left in, but commented out. Hopefully they make sense if you need them.

Some things you might want to watch out for when debugging your own scripts here.

Multi-line inputs. If the declaration has returns in it, you can run into problems. For me I take out all of the returns and get a flat declaration before processing.

Tabs and Spaces. There is a difference and they can trick you. There are places in the code where I search for whitespace/code breaks by looking for a space. Really I probably should look for a tab character too.

Formatting Output. Tabs and spaces are a pain on output too. Luckily we’re programmers here and are probably using a monospace font for our code. So I just used spaces for tabs. Matter of fact I wrote a little routine that generates a number of spaces. Then I made a convenience method that returns a tab. Then I can just put it in a print statement and have a “tab” of spaces. There is also a constant for the number of spaces in a tab, so you can easily change it is you want more or less.

How This Script Came To Be

I was away from coding for months and then got a gig converting a board game to the iPhone/iPad. With much excitement I updated my tools to XCode 4 and jumped into it. There are a lot of cool features and I was overall impressed. Then I wrote my first code and realized I hadn’t migrated my scripts that generate method headers by selecting the method declaration in the code.

One of my former co-workers, Brian Webster of Fat Cat Software, had written a cool script to do it, and we put them in XCode 3’s script folder and were off to the races.

You know how it is with things like installing script menu items or editing templates etc that you did once along time ago. I couldn’t figure out where the scripts went. Then I starting looking around online and realized quickly the Script Menu was GONE in XCode4. Matter of fact there was NO way to even get the selection and pass it to AppleScript and then set it back.

I looked around occasionally for a couple of months and never found a way to do it. But today I got a little fed up. Code Snippets just weren’t doing it for me, so I went looking again. General consensus was Apple had screwed its developers again and there was no way to do it.

Then I found Brad Oliver’s post on using Automator and Perl to do it. That was all I needed, I could figure out how to replace the selection now. I just needed to find those scripts again. And I couldn’t. So I emailed Brian and started building the Service to do the replacing. When I had that figured out, I hadn’t heard back from Brian, so I just started writing my own script to do the processing.

I wrote the scripts in Python which I had never used before. I’d avoided Python because the idea of using indentation as bracketing had just rubbed me wrong. But I’d been looking into doing some game programming and found there are a lot of 3D engines that are scripted via Python, so I’d decided to learn it. This seemed as good a time as any. I was pleasantly surprised. I made a lot of progress in a relatively short amount of time, especially considering I knew nothing of the language this morning.

Hopefully this post will help you both scripting XCode4 and commenting your code better. If you have any questions feel free to ask them in comments.

UPDATE: 07/17/2012 made a change to the script to handle routines with no parameters.