Sunday, April 20, 2014

How to use Interface Builder to create OS X Cocoa applications with Python

When programming Python I prefer to use native GUI on OS X. Very Simple OS X Cocoa Application using Python and Interface Builder is a good place to start. The example works with Python 3 on OS X 10.9.2 when PyObjC is installed following the instructions in one of my earlier posts: Python 3 and PyObjC.

Perl modules on Mac

I needed a few Perl modules that weren't installed on the standard Perl installation on my Mac (OS X 10.9.2). In How to install Perl modules on Mac OS X in 4 easy steps I found all the details needed. I didn't need to do step 1 (and 1.5) since this is the first thing I do on every new Mac instance. To summarize what I did in 3 steps to install the two modules I needed:

  1. sudo perl -MCPAN -e 'install Bundle::CPAN'
  2. sudo perl -MCPAN -e 'install Text::Iconv'
  3. sudo perl -MCPAN -e 'install HTML::TokeParser::Simple'

Wednesday, January 8, 2014

A suggestion for backup on Mac

A lot of options for backup on your Mac exists. I use Time MachineBackblaze, Crash PlanTransporterCarbon Copy Cloner, and other tools for different types of backup on different Macs. The challenging backup for me are my pictures. I want at least one backup not in my house. The size of this backup is large, and since I am using Aperture, the meta-data of the file-system has to be preserved. Large amount of data and continuous minor updates of the data also suggest that the backup solution should support incremental backups. My first thought was to use two Transporters, one at home and one at my office. This will give me the option to have two (or more) working copies of the Aperture data and everything will just work. However, this doesn't work because the Transporter doesn't support HFS+ (with meta-data), and Aperture uses the features of the file system extensively.

Newer versions of rsync does support HFS+ meta-data. I am currently using version 3.0.9 (3.1.0 has an annoying bug on OS X). OS X 10.9.1 comes with rsync version 2.6.9, and this is to old for our purpose. I installed version 3.0.9 using Homebrew.

The magic option of rsync that we need is -X, preserve extended attributes. We will also use the -a option to transfer the files in archive mode (ensures that symbolic links, devices, attributes, permissions, ownerships, etc. are preserved in the transfer). You might also add the -H option to preserve hard links and -v for verbose mode. If you are brave you might even add the --delete option. This will remove files at the backup folder that is no longer at the source folder. If you don't use this option you might end up with more files in the backup folder. See the manual pages of rsync for more details.

To back up a folder (the source folder with my Aperture library) I will use the following rsync command:

rsync -avXH --delete source-folder backup-folder

In my case the source and backup folders are located on different computers at home and work. I prefer that the file transfer over the network is using ssh. To do this I add the option --rsh=ssh. So from my home computer I will use the following command to backup my Aperture library to the backup folder of my work computer:

rsync -avXH --delete --rsh=ssh Pictures my.work.com:backup

I had to install rsync version 3.0.9 on both computers and I had to configure the remote computer to use that version of rsync and not the pre-installed version. You can do this command to check what version of rsync that will be executed on the remote computer my.work.com:

ssh my.work.com "rsync --version"

Saturday, April 6, 2013

Snowman shell prompt

My new bash shell prompt:

Snowman shell prompt

Matching the large amount of snow outside. A more detailed picture of the snowman:

snowman

Inspired by put a burger in your shell.

Tuesday, November 27, 2012

Python 3 and PyObjC

My main programming platform is OS X 10.8 and Python 3 (currently Python 3.3). In earlier blog posts I have discussed installing and using PyCrypto in this environment. My next attempt was to find a GUI solutions for this platform. I usually prefer native approaches when programming, and for OS X the Cocoa framework is the native approach. To get access to this from Python we need a bridge, and the bridge is called PyObjC. At the home page PyObjC seems like a dead project. But Ronald Oussoren is still doing some development, including Python 3 support. It is not straight forward to compile and install PyObjC for Python 3, but Giacomo Lacava provides the necessary steps. To summarize I have done the installation using the following steps:

  1. Fetch the latest code from Ronald Oussoren:
    hg clone https://bitbucket.org/ronaldoussoren/pyobjc
    cd pyobjc
  2. Compile and install PyObjC core:
    (cd pyobjc-core && python3 setup.py install)
  3. Compile and install the Cocoa, CoreData and Quartz frameworks:
    for i in Cocoa Quartz CoreData; do
      (cd pyobjc-framework-$i && python3 setup.py install)
    done
  4. Compile and install the rest of PyObjC (except the XgridFoundation framework):
    for i in pyobjc-framework-[^X]*; do
      (cd $i && python3 setup.py install)
    done

So far everything seems to work OK. You need Mercurial (hg) to perform the first step.

Wednesday, November 14, 2012

AES and RSA PyCrypto examples with Python 3

Earlier today I wrote about installing PyCrypto for Python 3 on OS X 10.8. I will use the opportunity to provide a few examples using PyCrypto to do AES and RSA encryption and decryption. I have created 3 programs. The first one, pycrypto-mkkey.py [src], generates an RSA key and saves it in two different files. One including the private key and one with only the public key (using the .pub extension). The stored private key is password protected with the given password. The program is used like this:

python3 pycrypto-mkkey.py rsa-key "passwd"

The second program, pycrypto-encrypt.py [src], use the public RSA key to encrypt a file. Actually, the file is encrypted using AES, and the AES key is then encrypted with RSA. First the program generates a new fresh AES key and saves it to disk encrypted with the RSA key. Then it uses this AES key to encrypt the file (from stdin) and write the encrypted data to stdout. The program is used like this:

python3 pycrypto-encrypt.py rsa-key.pub aes-key < plain > cipher

The third program, pycrypto-decrypt.py [src], use the private RSA key to decrypt the file. Actually, the file is decrypted using AES, and the AES key is decrypted using RSA. First the program decrypts the AES key with the private RSA key. Then it uses this AES key to decrypt the file (from stdin) and write the decrypted data to stdout. The program is used like this:

python3 pycrypto-decrypt.py rsa-key aes-key "passwd" < cipher

Se also the README file distributed together with the programs.

PyCrypto with Python 3 on OS X 10.8

On an updated Mac (in my case 10.8.2) with an updated version of Xcode  (in my case 4.5.2) compiling and installing PyCrypto for Python 3 (in my case 3.3) is not just simply running the setup.py script. The latest release of PyCrypto is 2.6 and it supports Python 3 (it has supported Python 3 since version 2.4). But my earlier attempts using Python 3.2 on OS X 10.8 failed since it couldn't locate the SDKs and the SDK for OS X 10.6 was not installed (see issue14498 and related posts to solve these issues). In Python 3.3 this is not an issue any more, but using the correct version of the compiler is. To get the build process to use the correct compiler I tried with the following build command (llvm-gcc-4.2 is the compiler we want to use on current OS X):

> CC=llvm-gcc-4.2 python3.3 setup.py build

In the beginning of the build process it seemed to use llvm-gcc-4.2, but finally it failed with this message:

unable to execute gcc-4.2: No such file or directory

The obvious solution is the create a symlink from llvm-gcc-4.2 to gcc-4.2:

> sudo ln -s /usr/bin/llvm-gcc-4.2 /usr/bin/gcc-4.2
> python3.3 setup.py build

Success! Then install it:

> python3.3 setup.py install

And we are done. A small example using PyCrypto to encrypt a text with AES:

> python3.3
Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 01:25:11)
GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from hashlib import sha256
>>> from Crypto import Random
>>> from Crypto.Cipher import AES
>>> from Crypto.Util import Counter
>>> pwd = "My secret password"
>>> key = sha256(pwd.encode()).digest()
>>> irv = Random.new().read(AES.block_size)
>>> icv = int.from_bytes(irv, "little")
>>> ctr = Counter.new(AES.block_size*8, initial_value=icv)
>>> cip = AES.new(key, AES.MODE_CTR, counter=ctr)
>>> msg = cip.encrypt('Attack at dawn'.encode())

To decrypt the message msg you need the password pwd or the key (the secret) and the initial counter value icv (can be public). The Python code to do this is left as an programming exercise for the reader (or you kan peek at pycryptex.py [src]).