Thursday, January 26, 2012

How to crack kindle DRM


I somehow zapped the original post.

Nutshell: I've become uncomfortable with the idea that I have access to my books only at Amazon's ok.
I wanted to take steps to protect my investment, and that involves cleaning the DRM from my purchased books.

The old ways - skindle or unswindle - are obsolete and haven't worked since mid-2011.
The new hotness is below.
The best way to utilize the toolkit is as a calibre plugin.

http://apprenticealf.wordpress.com/2010/02/11/hello-world/

This post will help you as well:
http://stream-recorder.com/forum/simplest-option-removing-drm-calibre-plugins-t8349.html


Update: I've attempted to seek remedy with Amazon and it's been to no avail. What seems to have happened is the case failures (which they've known about) cause a current across the Kindle. This causes resets, hard locks and the like. It's all out there on blogs.

Mine had the same case, but I didn't know of the problem so I kept the case on for months after the problems started, and it caused permanent damage to my year old Kindle.

Amazon is basically washing their hands of it saying that their stuff has a year warranty.
Fair enough; I'm the proud owner of a Nook.

Tuesday, January 24, 2012

mutable objects are great

TODO: pull together (find on web) a css/plugin for code snippets/syntax. Unconscionable.

You have to be careful with mutable objects in python.
Consider a structure like this:
>>> knights = { 'lancelot' : [ 1, 2, 3, 4, 5], 'robin': [1, 3, 5, 7, 9]}

In the code, say you're doing something with the list:

>>> brave =  knights.get('robin')
>>> brave.append(11)

If you then look at your dictionary, knights:
>>> print knights
{ 'lancelot' : [ 1, 2, 3, 4, 5], 'robin': [1, 3, 5, 7, 9, 11]}
When you assigned the list to brave, you're tagging the same list that lives in the dictionary, so anything you modify in it will modify the list in the dictionary as well.
Most of the time this is great, as it saves you from reassigning the list back into the dictionary after modifying it.
If you need to preserve the original list in the dictionary, make a copy:
>>> bravebrave = knights.get('robin')[:]
>>> bravebrave.append(13)
>>> print bravebrave
[1, 3, 5, 7, 9, 11, 13]
>>> print knights['robin']
[1, 3, 5, 7, 9, 11]

Sunday, January 22, 2012

part of me is thinking

I should have at least googled git and python before rolling my own.

thank you Edgar Cardona

He's given me permission to use this awesome robot rabbit for the page.
Here's his work

Thanks again Edgar, it's really cool.

Saturday, January 14, 2012

Vim Script, redux.

So if you tried using the script (you didn't, but if you HAD) on Windows, you would have discovered pretty quickly that it was terribly bugged.
I forgot git has its own Cygwinified shell when in Windows, so calling git from subprocess is going to bomb spectacularly.

What's worse, is since the git shell isn't really git, but a bash shell (ok ok Cygwin), you can't just pass a "git clone" argument anywhere easily.
You can, however, pass a shell script to auto-execute like any bash shell.
So, I made a few changes to the script.

It now has this function:
def call_git_windows(gitUrl):
    TEMP_FILE_PATH = os.path.expanduser('~\\vimfiles\\temp_sh.sh')
    # default git path
    path = os.path.join('C:', '\Program Files (x86)', 'Git', 'bin', 'sh.exe')
    tmp = os.open(TEMP_FILE_PATH, os.O_WRONLY|os.O_CREAT)
    print tmp
    os.write(tmp, ' '.join(['git clone', gitUrl]))
    os.close(tmp)
    cmd = ' '.join([path, '--login', '-i', TEMP_FILE_PATH])
    print cmd
    subprocess.call(cmd)
    os.remove(TEMP_FILE_PATH)     

It's pretty basic.
The major deficiencies are the hard coded git path (I looked, lazily, for an ENV variable that had it) and the hard coded TEMP_FILE_PATH.
They are both really "sensible defaults" and should probably be treated as such, abstracting into the function method signature or in a conf file when I expand the functionality to support saving a history of commands.

Next steps are tracking the installs in a pickle file, tying a config file to the process, and creating an alias.
Then there's just deployment testing.
I should write some unit tests for the thing too, once it graduates from "toy program" to "useful tool".
Maybe next weekend; babies are hard.

Sunday, January 8, 2012

72 hours into android - 100% sold

Back story: I'm coming from iPhone/iOS since the original iPhone.
While Apple reworked the landscape of what a phone is, their nature leaves the phone. . . stagnant. A consumer appliance.

The carriers are doing their best to do the same to the android - the Samsung Skyrocket I bought from AT&T was fairly absurd, having carrier IQ installed by default. (the nerve!)
But Android's linux.
And Linux can be freed.
So a root later, install ROM Manager, back up the stock ROM and flash a new Ice Cream Sandwich version, sans Carrier IQ. Yes, very much yes.

That was kind of impressive. I started looking for an iTunes-alike to synch my phone, blind to what I actually have.

Then I found Kies Air, and it was over. Turn this on, navigate to the page that your phone tells you to, and BAM! Set your music as ringtones, drag/drop whatever files/music you want into the phone or SD card, delete or add at will.

Fantastic.

The apps and customization options seem endless. I know there are/were apps for the iPhone, but this just feels - infinite. Free. The wilderness instead of the garden.

Customize your lock screen. Customize your input method. Customize ringtones, wallpapers, apps, widgets, launcher.

Phew.
See you later, back to playing with my phone.