Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • raj 7:23 pm on March 5, 2014 Permalink | Reply
    Tags: PyInstaller, PyQt,   

    Loading DLLs from a PyInstaller-packaged PyQt standalone application 

    I wanted to package a PyQt script as a standalone Windows .exe using PyInstaller, and I wanted the app to display a jpeg.

    It turned out that displaying a PNG was fine, but displaying a JPEG took a while to get working. PyQt uses a dll called `qjpeg4.dll` for decoding the jpeg, and PyInstaller doesn’t automatically bundle it into the package, so we have to tell PyInstaller to do so.

    There is still one problem though: when you run the .exe, where does PyQt try to load `qjpeg4.dll` from? It turns out that *it depends*..

    If you use the `–onedir` option for PyInstaller, the `imageformats/qjpeg4.dll` just needs to be in a directory called `imageformats`. No problem.

    If you use the `–onefile` option, PyInstaller unzips the binaries into a temp directory, and loads dlls from there. But for some reason, in the `–onefile` case, PyQt tries to load the dll from `qt4_plugins/imageformats/qjpeg4.dll`.

    I used SysInternals Process Monitor to figure this out…

    To make things easy, I just added an `imageformats` directory to my repo, and checked in the qjpeg4.dll.

    I also wanted to load a dll called `discid.dll`, required by python-discid. I checked into the root level of the repo, but couldn’t get the python package to load the dll properly, until I modified the PATH environment variable:

    #fix for loading discid.dll
    if getattr(sys, 'frozen', None):
         BASE_DIR = sys._MEIPASS
         BASE_DIR = os.path.dirname(__file__)
    os.environ['PATH'] = BASE_DIR + '\;' + os.environ.get('PATH', '')
    import discid

    My PyInstaller .spec file for the `–onefile` case looks like this:

    # -*- mode: python -*-
    a = Analysis([''],
    onefile_binaries = a.binaries + [('discid.dll', 'discid.dll', 'BINARY'),
                             ('qt4_plugins/imageformats/qjpeg4.dll', 'imageformats/qjpeg4.dll', 'BINARY'),
    pyz = PYZ(a.pure)
    exe = EXE(pyz,
              Tree('images', prefix='images'),
              console=True )
  • raj 11:46 pm on February 12, 2014 Permalink | Reply

    Thinking about the Wayback Machine 

    wayback boxes and arrows

  • raj 11:58 pm on February 7, 2014 Permalink | Reply

    BookReader usage in 2013 

    We measured whenever someone opened the IA BookReader. Usage more than doubled in 2013, to more than 5 people opening up the BookReader every second!

    For 2014, we won’t be able to produce the same data, since we now embed the BookReader on details pages, and a pageview now registers as a “bookreader open” event, even if the user doesn’t actually read the book.

  • raj 7:16 pm on October 31, 2013 Permalink | Reply
    Tags: , wordpress   

    BookReader embeds on 

    Blogs hosted at can now use BookReader embeds!

  • raj 6:46 pm on October 14, 2013 Permalink | Reply
    Tags: , iceland   

    Iceland: Where one in 10 people will publish a book –

  • raj 6:24 pm on September 5, 2013 Permalink | Reply
    Tags: dvd,   

    A robot for digitizing DVDs:

  • raj 7:51 pm on September 4, 2013 Permalink | Reply
    Tags: cnc,   

    MatrixShotâ„¢ 1.0 First Run

  • raj 11:32 pm on August 8, 2013 Permalink | Reply

    A python interface to 

    Jake pointed out today that he wrote a cool python wrapper for that made it easy to upload files. I added downloading support and a few other features:

    #The Internet Archive stores data in "items". You can query the archive using an item identifier:
    >>> import archive
    >>> item = archive.Item('stairs')
    >>> print item.metadata
    #Items contains files, which can be downloaded:
    >>> f = item.file('glogo.png')
    >>> #writes to disk
    #You can iterate over files:
    >>> for f in item.files():
    ...     print, f.sha1
    #You can use the IA's S3-like interface to upload files to an item.
    #You need to supply your IAS3 credentials in environment variables in order to upload.
    #You can retrieve S3 keys from
    >>> import os;
    >>> os.environ['AWS_ACCESS_KEY_ID']='x'; os.environ['AWS_SECRET_ACCESS_KEY']='y'
    >>> item.upload('myfile')
  • raj 6:01 pm on July 17, 2013 Permalink | Reply
    Tags: canon, chdk, magic lantern   

    Magic Lantern is third-party firmware (like CHDK) that works on Canon DSLRs:

  • raj 11:44 pm on June 26, 2013 Permalink | Reply
    Tags: , uploader   

    Plotting uploads/day 

    We are beta testing a HTML5 Uploader, and I wanted to see how much use it was getting. Here is how I plotted the usage. First, install ipython html notebook, then install matplotlib 1.3rc2 to use the xkcd style, then start iPython notebook:

    $ source ~/pyenvs/notebook/bin/activate
    $ ipython notebook --profile=nbserver

    Then, in iPython notebook, use the advanced search engine to see how many uploads per day we were getting:

    import json
    import urllib
    import datetime as dt
    urlbase = ''
    date = dt.datetime.utcnow()
    for i in range(90):
        date -= dt.timedelta(days=1)
        params = {'q':'scanner:"Internet Archive HTML5 Uploader" AND publicdate:'+date.strftime('%Y-%m-%d'),
        url = urlbase % urllib.urlencode(params)
        f = urllib.urlopen(url)
        o = json.load(f)

    Now that I have the data, I can plot it, using xkcd-style:

    #Turn on XKCD style
    plot(x, y)
    plt.title("HTML Uploader Items/Day")
    #Save PNG
    fig = plt.gcf()

    It looks like this:

compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc