Thanks for Making it Unnecessarily Hard to Get a Harry Potter Book on My Daughter’s Kindle

Exclusive Dealers

Apparently, JK Rowling made a deal with Sony to exclusively sell Harry Potter e-books on the Sony e-book through the Pottermore site, through January 2012.

What I found out today was that I still had to go to that site in order to buy any e-book version of the Harry Potter books. That posed a major inconvenience in itself because my daughter got $35 in Amazon gift cards to buy Kindle books for her new Kindle that her grandfather bought her. She said she wanted to buy the Harry Potter books with those. The (first) problem with the Pottermore Shop site? Those gift cards would be useless.

User Unfriendliness

I went ahead and went through the motions to set up a Pottermore Shop account to buy the boxed set and then decided, just before checkout but after creating an account, to bail out of the process and go and buy the individual books at Amazon instead. If you go to the page for Harry Potter on the Kindle Store, you’ll find that all links go back to the Pottermore store.

Screen Shot 2013-12-26 at 2.03.49 PMSo, I resigned myself to going to the Pottermore.com site (manually typing it in.) I found that the site no longer recognized me as signed in. So, I used the username and password that I had previously created and stored (of course, the initial sign-up wouldn’t allow copy-and-paste) and found that my login wasn’t accepted. I tried copying and pasting and manually typing to no avail, until I was locked out of that “account”. In between attempts, I even tried a password reset. I was able to “reset” my password, but not able to use it to login.

I decided to sign my daughter up for an account and try again. It was then that I discovered that Pottermore.com apparently doesn’t use emails as usernames, but instead, gives you an option to pick one of five randomly generated [two-word + number] usernames. So, the login process for the shop and the main site are different.

Sony’s Half-Baked Download Control

Once I had purchased the boxed set, I still had to download the individual books separately. For that I had to link an account. Fortunately, Kindle was one of the options available, and I could authorize downloads to that account. Weird part of the download process is that you’re given 8 downloads per book, so you have some limitation as to how many places you can send it. Weirder still is that “direct download” is one of those options (I’m assuming that means a DRM-less copy). Why bother with the limitation? If someone is going to steal, they just have to do the unrestricted download once, but if someone legitimately chooses crappy e-book services that shut down, then they might (amazingly) run out of downloads.

Kudos for Sticking it to Amazon or Whomever, JK Rowling, But…

I can’t really fault JK Rowling for finding a way to break free of Amazon’s e-book cost structure. There are many smaller authors wary of getting sucked into Amazon’s vise grip. However, I can imagine that there are many young fans out there that got a Kindle for Christmas or their birthday along with an Amazon gift card, and they just wanted to have Harry Potter on their Kindle. Their gift card is no good outside of Amazon.

I go shopping on The Pragmatic Bookshelf for many of my technical books, so I can appreciate the value that can come from an independent publisher of books, but those books have no download restrictions on them. The only copyright enforcement on the e-book version of Pragmatic Bookshelf is the honor system (and the intended recipient’s name at the bottom.) I jump through hoops to download those books, but the audience of a Pragmatic is highly technical, so a few technical hurdles isn’t unreasonable.

Maybe the only kids who ever get e-book readers are kids whose dads are willing to contribute cash when the gift cards are of no use and willing to jump through hurdles to get the books downloaded and set up. I hope so, because then the minor inconveniences of 1000s of fans are worth the sweetened deal you got, and your fans will never know the difference.


Monkey patching if you need to force an error in delayed_job

I wanted to force an error condition in my cucumber tests, but the code ran through a DelayedJob, so I couldn’t redefine the code running under the .delay chain, because the DelayedJob worker will reload the normal code base for its processing. I finally realized that simply patching the delay instance method to return self for the class in question would bypass the delayed job.

def force_query_error
  ObjectDelayed.class_eval do
    alias :old_delay :delay
    alias :old_query :query
 
    def delay
      self
    end
 
    def query
      raise 'monkey'
    end
  end
end
 
def restore_query
  ObjectDelayed.class_eval do
    remove_method :query
    remove_method :delay
    alias :query :old_query
    alias :delay :old_delay
  end
end

This is not to be confused will actually allowing DelayedJob to do its thing:

 
When(/^I wait for processing of jobs$/) do
  Delayed::Worker.new(:quiet => false).work_off
  Timeout::timeout(10) do
    until Delayed::Job.count == 0 do
    end
  end
end

How long until a randomly chosen string of letters with no results shows up in Google if I include it in a post?

Inquiring minds want to know. So, I’m including a string of letters that looks Slavic – yznvenskya – in the first couple of lines of a post.

Update:  Looks like it took less than 16 minutes to show up.

Screen Shot 2013-05-11 at 2.13.19 AM


On Mac OSX Lion: “ERROR: Error installing ruby-oci8: ERROR: Failed to build gem native extension”

Running Mac OSX Lion, trying to bundle install a project that included the ruby-oci8 gem, I received the following error:

Building native extensions.  This could take a while...
ERROR:  Error installing ruby-oci8:
	ERROR: Failed to build gem native extension.

The fix:

Fortunately, the 64-bit client for Oracle has now been updated for Lion/Mountain Lion. Download them from Instant Client Downloads for Mac OSX (Intel x86). Downloading “Basic Lite” and the “SDK” under Version 11.2… (64-bit) worked for me.

Unzip the files to ~/instantclient_11_2 so that the sdk directory and libs are directory beneath it:

$ ls ~/instantclient_11_2 
BASIC_LITE_README    genezi               libclntsh.dylib.11.1 libocci.dylib.11.1   libocijdbc11.dylib   ojdbc6.jar           uidrvci
adrci                libclntsh.dylib      libnnz11.dylib       libociicus.dylib     ojdbc5.jar           sdk                  xstreams.jar

Add the following to my .zlogin or .bash_login

export DYLD_LIBRARY_PATH=~/instantclient_11_2

Rerun the login shell (exec $SHELL -l) or restart your shell.

Link the libclntsh.dylib. in ~/instantclient_11_2 to a versionless lib file name:

ln -s libclntsh.dylib.11.1 libclntsh.dylib

Your ruby-oci8 should install now.

zsh grep and mvim: search for a string in a directory in file type, and open that point

open_all {pattern} {extension}

#!/bin/zsh
grep -n $1 **/*$2 | sed 's/^\([a-zA-Z_/.]*\):\([0-9]*\).*$/\2 \1/' | while read line file
do
  mvim --remote-tab-silent +$line $file
done

Usage:

# find all occurrences of "def" as a whole word and open the files in separate tabs:
open_all '\<def\>' .rb

Fun with the Ruby & (unary ampersand) and String#to_proc

In trying to grasp the unary & operator in ruby, I ran across [Stupid Ruby Tricks: String#to_proc].

Therefore, I decided I had to further twist the language features to my own will.

Like many things in Ruby with duck-typing, the following syntax:

('a'..'z').map &:upcase

…makes use of the fact that Symbol has a #to_proc method, which means that the following call is an explicit version of the above call.

('a'..'z').map &:upcase.to_proc

If you wanted to allow for a shorthand notation for map, then you could add #to_proc to String, as follows:

class String
  def to_proc
    eval "Proc.new { |*args| args.first#{self} }"
  end
end

This allows for the following call:

[1,2,3].map &'*2'                     # [2, 4, 6]

…which is equivalent to:

[1,2,3].map { |*args| args.first*2 } # note: no space

…But what if I wanted to specify a library function to have the Array members passed to? (Certainly, this is venturing deeper into solving a problem that doesn’t exist.) Also, what if I want to pass an Array for the arguments?

class String
  def to_proc
    # assume an initial word character is a library function, otherwise evaluate as before
    if /^\w/ =~ self
      eval "Proc.new { |*args| #{self}(*args.first) }"
    else
      eval "Proc.new { |*args| args.first#{self} }"
    end
  end

The above code will expand an embedded Array into an argument list:

[[2,2],[9,3],[64,4]].map &'Math.log'  # [1.0, 2.0, 3.0]
[1.0, 2.0, 4.0].map &'Math.sqrt'      # [1.0, 1.4142135623730951, 1.7320508075688772]
[1,2,3].map &'*2'                     # [2, 4, 6]
[[2,2],[9,3],[64,4], 4].map &'Math.log' # [1.0, 2.0, 3.0, 1.3862943611198906]

Twitter Bootstrap Modal Won’t Load Content from Another (“Remote”) Page

Short answer

You apparently need a skeleton [modal ... modal-body ... /modal] for your data-target, not just an empty modal with the data-target.

A Programmer’s False Assumptions – The API is Broken or Old

Initially, I was concerned that my Rails plugin wasn’t using a version of Bootstrap that didn’t include the remote loading of a page into the modal (via href attribute). That functionality has only existed since 2.0.4.

However, when I checked the script being loaded into the project against the current bootstrap-modal.js on github, the MODAL DATA-API section was the same. Repeated checks of the javascript being loaded into my project confirmed that the code was up-to-date enough.

Maybe a Little Too Helpful

The forums discussing how to load remote content into a Bootstrap Modal suggested that the data-target div could be empty:
Original calling page sample:
The contents of the calling page div never changed.

<a class="btn small" href="/stuff/1/edit" data-toggle="modal" data-target="#editstuff">Settings...</a>
.
.
.
<div id="editstuff" class="modal hide">This should not display</div>

“Remote” page sample

...extra code here...
<div id="editstuff" class="modal hide">
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal">×</button>
<h3 id="myModalLabel">Remote header</h3></div>
<div class="modal-body">Actual edit stuff</div>
<div class="modal-footer"><button class="btn" data-dismiss="modal">Cancel</button> <!-- just a sample --> 
<button class="btn" data-dismiss="modal">Close</button> 
<button id="save_btn" class="btn btn-primary">Save changes</button></div>
</div>
...extra code here...

What Was Really Happening

The documentation states that, “If a remote url is provided, content will be loaded via jQuery’s load method and injected into the .modal-body.”

From there, I put a stub modal-body in my calling page’s modal and discovered that modal-header, modal-body, and modal-footer appeared to be getting replaced now!
New calling page:

<div id="editstuff" class="modal hide">
<div class="modal-body"><!-- content will be loaded here --></div>
</div>

Experimenting with Rails’ String Manipulation from ActiveSupport::CoreExtensions::String::Inflections

This is my experimentation with the string manipulation methods used [largely internally] in Rails. This is largely a repeat of the documentation here, but I did dig into pluralize/singularize and a couple of other examples more in depth. Look at [path to active_support gem version]/lib/active_support/inflections.rb for the full list of plural, singular, irregular, and uncountable regular expressions and words.

require 'active_support/core_ext/string/inflections'
# camelcase, camelize 
"separate_words".camelize # SeparateWords
"active_record".camelcase(:lower) # separateWords
 
# classify - converts to first upper CamelCase, last word made singular
"this_and_thats".classify # ThisAndThat
 
# constantize - looks for declared constant with the name specified
"Integer".constantize # returns constant [class] Integer
"integer".constantize # results in NameError: wrong constant name integer
"Boo".constantize # results in NameError: uninitialized constnat Boo (assuming it isn't declared)
 
# dasherize - underscores to dashes
"a_b_c".dasherize # a-b-c
 
# demodulize - removes module namespace from module in string.
ModuleA::SubModule::Module".demodulize # Module
 
# foreign_key - create name of a foreign key to class name, optional parameter to separate class from id
"Integer".foreign_key # integer_id
"Integer".foreign_key(false) # integerid
 
# humanize - capitalizes first word, down cases rest, turns underscores into space.
"McLean".humanize # Mclean
"Apple_Banana".humanize # Apple banana
 
# parameterize - replaces special characters in a string, default separator is '-'
#   - whitespace is a special character here, underscore is not
#   - consecutive special characters become a single separator
#   - converts to lowercase
"Apple@!Banana".parameterize # "apple banana"
 
# pluralize 
"raman".pluralize # "ramen" -- apparently, "man" --> "men" even on a made-up word
"jazz".pluralize # "jazzs" 
"box".pluralize # "boxes"
"beep".pluralize # "beeps"
"moose".pluralize # "mooses"
"rhombus".pluralize # "rhombuses"
"octopus".pluralize # "octopi"
 
# singularize
"ramen".singularize # "raman"
"jazzes".singularize # "jazze"
"boxen".singularize # "boxen" -- yeah, not a real word again
 
# tableize - snake_case string and pluralize last word
"RedHeadedStepchild".tableize # "red_headed_stepchildren"
 
# titlecase / titleize - capitalize all words, 
"two_three-four.five:six".titleize # "Two Three Four.Five:Six"
 
# underscore - snake_case words (opposite of CamelCase) and covert :: to /
"Number::OneTwo::Integer".underscore # "number/one_two/integer"

Background on Mac OS X Lion Gets Stuck on Gray Linen Background and Menu Bar is Black

I’ve been having this problem intermittently when plugging in and unplugging my external monitor.

I found a fix to the black menu bar that involved going into System Preferences->Desktop & Screen Saver and toggling the “Translucent Menu Bar” setting.

However, my backgrounds were still the gray linen background. Upon further searching for that system, I found that killing the Dock.app fixing the problem via one of the following code (which I put in my ~/bin as “fixLinenBackground”)

sudo kill -HUP `ps -ef | grep [D]ock.app | awk '{print $2}'`

or

killall Dock.app

Script to Change the Title of Your Terminal Window

I decided to create a small bash script to change the title of my current terminal window in bash on my Mac:

change_title:
#!/bin/bash
 
echo -ne "\033]0;" $* "\007"

The script then runs as:

change_title Your title goes here.